sql >> Database teknologi >  >> RDS >> Mysql

Fejl 1005 i MySQL (fra fremmednøglesyntaks?)

Dine fejl er forårsaget på grund af forkert fremmednøglesyntaks.

Men Jeg synes, du skal bruge ID-felter i stedet for at lave sammensatte primærnøgler for strenge . Der er et par problemer med din metode...

  • Det vil gøre det sværere for DB'en at sammenføje tabeller sammenlignet med at bruge et heltalsfelt (ID) til at joine (sværere ==mere behandlingstid).

  • Det er gyldigt at have flere personer med samme navn, selv ved at bruge en mellembogstav.

  • Hvad sker der, hvis du bliver nødt til at ændre nogens navn? Enten fordi det blev gemt forkert, eller de blev gift eller noget... Det betyder, at du ikke kun skal opdatere din employee tabel, men works tabel og enhver anden tabel, du har brugt navnet som en fremmednøgle.

Tag et kig på dette:http://sqlfiddle.com/#! 2/2dc8c/3/0

Jeg har tilføjet et tabel-id til hver tabel . Det er en unsigned int , hvilket betyder, at det ikke kan være negativt (fordi det ikke giver meget mening). Det er også auto_increment , hvilket betyder, at hver gang du tilføjer en række til tabellen, bliver dette ID automatisk genereret og stiger med 1.

    create table Employee (
          Employee_ID int unsigned auto_increment primary key,

          Lastname    varchar(10),
          FirstName   varchar(10),
          MidInitial  char(1),

          gender      char(1),

          street      varchar(10),
          city        varchar(10),

          unique (Lastname, FirstName, MidInitial)
      );

Du ville tilføje ting til denne tabel som denne:

    insert into Employee (Employee_ID, LastName, FirstName, MidInitial) 
                   values (null,       'Smith',  'John',    'K');

null bliver det automatisk genererede ID. Det vil være unikt for hver række.

Også en unik begrænsning betyder, at kombinationen af ​​disse felter skal være unik i tabellen. Men med et stort nok firma vil jeg vædde på, at to personer vil have det samme navn. I det virkelige liv vil jeg foreslå at fjerne denne unikke begrænsning.

Jeg lavede lignende ændringer i firmatabellen...

     create table company(
         company_ID      int unsigned auto_increment primary key,

         company_name    varchar(20),
         city            varchar(10),

         unique (company_name)
    );

Ting kunne tilføjes som:

     insert into company values (null, 'Taco Bell', 'Paris'); 

Så... for works .... i stedet for at gemme det fulde navn på hver person og det fulde firmanavn igen og igen i denne tabel, skal vi nu kun gemme ID'erne.

    create table Works (
         works_id      int unsigned auto_increment primary key,

         employee_id   int unsigned, 
         compay_id     int unsigned,  

         salary        numeric(8,2), 

         foreign key (employee_id) references Employee (employee_id), 
         foreign key (compay_id) references company (company_id) 
    );

Du kan tilføje ting til works sådan her:

    insert into Works values (null, 1, 1, '10.00');

Da John Smith var vores første medarbejder, ville hans Employee_ID være 1. For at bekræfte det, prøv bare at select * from Employee where FirstName='John' and LastName='Smith' . Taco Bell ville også få company_id =1. Ved at indsætte disse værdier i works , det betyder, at John nu arbejder hos Taco Bell.

Jeg vil også foreslå, at du tilføjer felter som start_date og end_date og job_title til dit arbejdsbord. Og du vil også gerne tage særligt hensyn til eventuelle unikke begrænsninger for dette bord. Folk kan arbejde for den samme virksomhed mere end én gang. De kan også have forskellige jobs.

Når du vil have dine data ud igen, vil du bruge en forespørgsel som denne:

  select FirstName, MidInitial, LastName, 
         Company_Name, 
         Salary 

  from   employee

         join works 
           on works.employee_id = employee.employee_id

         join company 
           on works.company_id = company.company_id 

hvilket bare er en fancy måde at sige dette på:

  select FirstName, MidInitial, LastName, 
         Company_Name, 
         Salary 

  from   employee, works, company

  where  employee.employee_id = works.employee_id and

         company.company_id = works.company_id  

Nogle bemærkninger om databaseting...

  • Vælg en navnekonvention, og hold dig til den! Hvis du vil bruge CamelCase , brug det overalt. Hvis you_want_to_use understreger i dine navne, brug dem overalt. Der er tonsvis af navnekonventioner at vælge imellem:præfikser attributter (kolonner/felter) med tabelnavnet, brug af almindelige forkortelser (eller ej), hvor der bruges store bogstaver (eller ej)... dette kommer for det meste ned til personlige præferencer, men der er artikler derude om fordele og ulemper ved at bruge visse. Sidste bemærkning, _bare fordi du kan bruge mellemrum i et navn,__ betyder det ikke, at du skal. `Almost all` databaser lader [you use spaces] i navne, hvis du vil, men det kan forårsage en masse problemer senere.

  • Tabelnavne bør ikke være i flertal. Dette er et kæledyr for mig, og her er hvorfor:Vi ved, at et bord vil indeholde mange rekorder... mange mennesker/personer, mange ansatte, flere virksomheder, flere poster af hvilken som helst type eller art. Hver række beskriver kun én af disse ting. Nogle gange giver det bare ikke engang mening at have navnet i flertal. Andre gange er det tvivlsomt - ligesom works bord. Hvis du nogle gange gør det i flertal, og nogle gange gør det ental, kan det blive forvirrende senere. Ved blot at gøre det hele ental, giver det stadig god mening, og du skifter ikke frem og tilbage eller skal slå det nøjagtige navn op, når du skriver forespørgsler.

  • Datatyper er vigtige og prøv at være ensartet på tværs af tabeller for lignende felter (som alle id s samme type; gør alle booleske felter alle bits eller heltal eller hvad som helst, bare gør dem ens). Der er forskellige størrelser af heltalstyper, du kan vælge imellem. Tænk over størrelse, ydeevne og hvad der passer til dine behov. Beslut dig for, om du virkelig har brug for en nvarchar, eller om en varchar er i orden.

    • Datoer bør aldrig gemmes som en streng. Brug den relevante datatype for dato, dato, klokkeslæt eller tidsstempel . Dette vil hjælpe dig meget senere, når du skal hente det, sammenligne det eller bruge det i beregninger. En anden vigtig beslutning er, hvordan du valgte at håndtere tidszoner . Jeg kan godt lide at gemme alt i UTC og håndtere enhver tidszoneoffset ting på frontend, når informationen præsenteres for brugeren. Dette holder alt konsekvent, og jeg behøver ikke bekymre mig om, om rækken blev indsat kl. 18.00 baseret på min brugers computertid, brugerens browsertid, min databases tid eller serverens tid.

  • Medtag et ID felt det er unikt for rækken i hver tabel. Den nemmeste måde at gøre dette på er at bruge en auto_increment (mysql) eller identity(1,1) (sql server) felt, så databasen holder styr på det for dig. Disse værdier kan nulstilles eller genindsættes, hvis du har brug for det.

  • Lær at bruge normalisering .

  • Lær hvilke transaktioner gør og hvorfor de er vigtige... også selvom du ikke bruger dem.

  • Lær om de forskellige slags joinforbindelser . Dette er en af ​​de bedste forklaringer Jeg har nogensinde set. Det vigtigste at være opmærksom på er, om sammenføjningen skal være en ydre eller indre sammenføjning.

  • Lær om SQL-injektion og endnu vigtigere, hvordan for at forhindre det (Dette link er til PHP).

  • Hvis du bruger PHP, skal du ikke bruge den gamle mysql_ klasse. Brug i stedet PDO eller MySQLi_ . Info...

  • Det store ved databaser er dataintegritet, validering og rensning . Brugere vil ønske at lægge alle slags sjuskede, beskidte data ind i dine tabeller. Er det MO eller Missouri? Kvinde, K, kvinde, pige eller ja? Er lønnen 15,00 i timen, 50k årligt eller 3.000 en lønseddel? Er det 31/12/2013, 31/12/2013, 31/12/13, 31/12 2013 eller 31. december 2000 og tretten?

  • Beslut om du vil tillade NULL eller ikke. Det gør tingene mere komplicerede på grund af triple state logic, og du bliver nødt til at tjekke for det senere. Nogle mennesker beslutter at bruge en tom streng i stedet for. NULL er mere en tilstand end en faktisk værdi, og det betyder udefineret eller ukendt - værdien kan være hvad som helst. Jeg bruger null fordi en tom streng nogle gange er en gyldig værdi for et felt. For eksempel indstilling af Middle_Initial at være lig med en tom streng kan betyde, at personen ikke har en midterste initial, eller det kan betyde, at du bare ikke ved, hvad det er. For mig er disse ting anderledes. For andre mennesker er forskellen ligegyldig. Overvej bare tal... er 0 det samme som ukendt?

  • Hvis ikke andet, så vær bare konsekvent.



  1. Atomic OPDATERING .. VÆLG i Postgres

  2. Hvordan ændrer jeg adgangskoden til root-brugeren i MySQL?

  3. SQL Server Passthrough-forespørgsel som grundlag for et DAO-postsæt i Access

  4. Kan jeg bruge pt-online-schema-change til at ændre en primær nøgle?