sql >> Base de Datos >  >> RDS >> Mysql

La normalización dificulta las uniones entre varias tablas

No voy a hablar de faltas de ortografía. Dado que está importando los datos, los errores ortográficos se manejan mejor en una tabla de etapas.

Veamos esta versión ligeramente simplificada.

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

Aunque mucha gente cree firmemente que el código postal determina la ciudad y el estado en los EE. UU., ese no es el caso. Los códigos postales tienen que ver con la forma en que los transportistas manejan sus rutas, no con la geografía. Algunas ciudades se extienden a ambos lados de las fronteras entre estados; las rutas de un solo código postal pueden cruzar las fronteras estatales. Incluso Wikipedia lo sabe , aunque sus ejemplos pueden estar desactualizados. (Las rutas de entrega cambian constantemente).

Entonces tenemos una tabla que tiene dos claves candidatas,

  • {nombre_de_la_tienda}, y
  • {street_num, street_name, city, state_code, zip_code, iso_country_code}

No tiene atributos no clave. Creo que esta tabla está en 5FN. ¿Qué opinas?

Si quisiera aumentar la integridad de los datos de los nombres de las calles, podría comenzar con algo como esto.

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.

Podría (y probablemente debería) repetir este proceso para nombres de ciudades, nombres de estados (códigos de estado) y nombres de países.

Algunos problemas con su enfoque

Aparentemente, puede ingresar un número de identificación de calle para una calle que se encuentra en los EE. UU., junto con la identificación del país para Croacia. (El "nombre completo" de una ciudad, por así decirlo, es el tipo de dato que probablemente desee almacenar para aumentar la integridad de los datos. Eso probablemente también sea cierto para el "nombre completo" de una calle).

El uso de números de identificación para cada bit de datos aumenta considerablemente la cantidad de uniones requeridas. El uso de números de identificación no tiene nada que ver con la normalización. El uso de números de identificación sin las restricciones únicas correspondientes en las claves naturales (un error completamente común) permite la duplicación de datos.