Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Chuẩn hóa làm cho việc kết hợp trên nhiều bảng trở nên khó khăn

Tôi sẽ không nói lỗi chính tả. Vì bạn đang nhập dữ liệu nên các lỗi chính tả sẽ được xử lý tốt hơn trong bảng dàn trang.

Hãy xem phiên bản đơn giản hơn một chút này.

create table stores
(
  store_name varchar(50) primary key,
  street_num varchar(10) not null,
  street_name varchar(50) not null,
  city varchar(50) not null,
  state_code char(2) not null,
  zip_code char(5) not null,
  iso_country_code char(2) not null,
  -- Depending on what kind of store you're talking about, you *could* have
  -- two of them at the same address. If so, drop this constraint.
  unique (street_num, street_name, city, state_code, zip_code, iso_country_code)
);  

insert into stores values 
('Dairy Queen #212',  '232', 'N 1st St SE',   'Castroville',  'CA', '95012', 'US'),
('Dairy Queen #213',  '177', 'Broadway Ave',  'Hartsdale',    'NY', '10530', 'US'),
('Dairy Queen #214', '7640', 'Vermillion St', 'Seneca Falls', 'NY', '13148', 'US'),
('Dairy Queen #215', '1014', 'Handy Rd',      'Olive Hill',   'KY', '41164', 'US'),
('Dairy Mart #101',   '145', 'N 1st St SE',   'Castroville',  'CA', '95012', 'US'),
('Dairy Mart #121',  '1042', 'Handy Rd',      'Olive Hill',   'KY', '41164', 'US');

Mặc dù nhiều người tin chắc rằng mã ZIP xác định thành phố và tiểu bang ở Hoa Kỳ, nhưng không phải vậy. Mã ZIP liên quan đến cách các nhà cung cấp dịch vụ lái xe tuyến đường của họ, không liên quan đến địa lý. Một số thành phố nằm giữa biên giới giữa các tiểu bang; các tuyến đường mã ZIP duy nhất có thể vượt qua các tuyến tiểu bang. Ngay cả Wikipedia cũng biết điều này , mặc dù các ví dụ của họ có thể đã lỗi thời. (Các tuyến đường giao hàng thay đổi liên tục.)

Vì vậy, chúng tôi có một bảng có hai khóa ứng viên,

  • {store_name} và
  • {street_num, street_name, city, state_code, zip_code, iso_country_code}

Nó không có thuộc tính không phải khóa. Tôi nghĩ rằng bảng này nằm trong 5NF. Bạn nghĩ gì?

Nếu tôi muốn tăng tính toàn vẹn của dữ liệu cho tên đường, tôi có thể bắt đầu với một cái gì đó như thế này.

create table street_names
(
  street_name varchar(50) not null,
  city varchar(50) not null,
  state_code char(2) not null,
  iso_country_code char(2) not null,
  primary key (street_name, city, state_code, iso_country_code)
);  

insert into street_names
select distinct street_name, city, state_code, iso_country_code
from stores;

alter table stores
add constraint streets_from_street_names
foreign key             (street_name, city, state_code, iso_country_code)
references street_names (street_name, city, state_code, iso_country_code);
-- I don't cascade updates or deletes, because in my experience
-- with addresses, that's almost never the right thing to do when a 
-- street name changes.

Bạn có thể (và có lẽ nên) lặp lại quy trình này đối với tên thành phố, tên tiểu bang (mã tiểu bang) và tên quốc gia.

Một số vấn đề với cách tiếp cận của bạn

Dường như bạn có thể nhập số id đường phố cho một đường phố ở Hoa Kỳ, cùng với id quốc gia cho Croatia. (Có thể nói, "tên đầy đủ" của một thành phố là loại dữ kiện mà bạn có thể muốn lưu trữ để tăng tính toàn vẹn của dữ liệu. Điều đó có lẽ cũng đúng với "tên đầy đủ" của một con phố.)

Sử dụng số id cho mỗi bit dữ liệu sẽ làm tăng đáng kể số lượng liên kết cần thiết. Sử dụng số id không liên quan gì đến quá trình chuẩn hóa. Sử dụng số id mà không có ràng buộc duy nhất tương ứng trên các khóa tự nhiên - một lỗi hoàn toàn phổ biến - cho phép dữ liệu trùng lặp.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lệnh H2 runningcript biến tất cả các tên bảng thành chữ hoa

  2. Lỗi quyền Mysql với 'tải dữ liệu'

  3. Một đường tắt để cập nhật một hàng bảng trong cơ sở dữ liệu?

  4. Phân biệt so với Nhóm theo

  5. phpMyAdmin Lỗi SQL Từ khóa không được công nhận gần FIELDS