sql >> Databáze >  >> RDS >> Mysql

Normalizace ztěžuje spojení napříč více tabulkami

Nebudu mluvit o překlepech. Protože data importujete, překlepy se lépe řeší v pracovní tabulce.

Podívejme se na tuto mírně zjednodušenou verzi.

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

Ačkoli mnoho lidí pevně věří, že PSČ určuje město a stát v USA, není tomu tak. PSČ mají co do činění s tím, jak dopravci řídí své trasy, nikoli s geografií. Některá města se rozkročí na hranicích mezi státy; trasy s jedním PSČ mohou protínat státní hranice. Ví to i Wikipedie , ačkoli jejich příklady mohou být zastaralé. (Trasy doručení se neustále mění.)

Máme tedy tabulku, která má dva kandidátní klíče,

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

Nemá žádné neklíčové atributy. Myslím, že tato tabulka je v 5NF. Co si o tom myslíte?

Pokud bych chtěl zvýšit integritu dat pro názvy ulic, mohl bych začít něčím takovým.

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.

Tento proces byste mohli (a pravděpodobně měli) zopakovat pro názvy měst, názvy států (kódy států) a názvy zemí.

Některé problémy s vaším přístupem

Zjevně můžete zadat identifikační číslo ulice, která se nachází v USA, spolu s identifikačním číslem země pro Chorvatsko. (Takříkajíc „celé jméno“ města je druh skutečnosti, kterou pravděpodobně chcete uložit, abyste zvýšili integritu dat. To pravděpodobně platí i pro „celé jméno“ ulice.)

Použití identifikačních čísel pro každý bit dat výrazně zvyšuje počet požadovaných spojení. Použití identifikačních čísel nemá nic společného s normalizací. Použití identifikačních čísel bez odpovídajících jedinečných omezení na přirozených klíčích – naprosto běžná chyba – umožňuje duplicitní data.




  1. Ladění spouštěčů MySQL

  2. Jak odstranit jeden soubor z úložiště médií?

  3. Vyberte ..... kde .... NEBO

  4. Převést „smalldatetime“ na „datetime“ v SQL Server (příklady T-SQL)