Mysql
 sql >> база данни >  >> RDS >> Mysql

Нормализирането затруднява свързванията в множество таблици

Няма да говоря за правописни грешки. Тъй като импортирате данните, правописните грешки се обработват по-добре в етапна таблица.

Нека разгледаме тази леко опростена версия.

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');

Въпреки че много хора твърдо вярват, че пощенският код определя града и щата в САЩ, това не е така. Пощенските кодове са свързани с това как превозвачите управляват своите маршрути, а не с географията. Някои градове пресичат границите между държавите; маршрутите с един пощенски код могат да пресичат държавни линии. Дори Уикипедия знае това , въпреки че техните примери може да са остарели. (Маршрутите за доставка се променят постоянно.)

Така че имаме таблица, която има два кандидат ключа,

  • {store_name} и
  • {street_num, street_name, city, state_code, zip_code, iso_country_code

Той няма неключови атрибути. Мисля, че тази таблица е в 5NF. Какво мислите?

Ако исках да увелича целостта на данните за имената на улиците, може да започна с нещо подобно.

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.

Можете (и вероятно трябва) да повторите този процес за имена на градове, имена на щати (кодове на щати) и имена на държави.

Някои проблеми с вашия подход

Очевидно можете да въведете идентификационен номер на улица за улица, която е в САЩ, заедно с идентификационния номер на държавата за Хърватия. („Пълното име“ на град, така да се каже, е фактът, който вероятно искате да съхраните, за да увеличите целостта на данните. Това вероятно важи и за „пълното име“ на улица.)

Използването на идентификационни номера за всеки бит от данни значително увеличава броя на необходимите присъединявания. Използването на идентификационни номера няма нищо общо с нормализирането. Използването на идентификационни номера без съответни уникални ограничения за естествените ключове – напълно обичайна грешка – позволява дублиране на данни.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL заявка със средно и групиране по

  2. Как да ограничим достъпа до MySQL порт

  3. Как да инсталирате Ruby on Rails с mysql и да го накарам да работи, ръководство стъпка по стъпка?

  4. Как да избягвам низове в pdo?

  5. mysql:разделяне на стойността на varchar и вмъкване на части