Mysql
 sql >> Baza danych >  >> RDS >> Mysql

SQL:Tworzenie tabeli relacji z 2 różnymi auto_increment

Koncepcje

Źle zrozumiałeś kilka podstawowych pojęć i wynikają z tego trudności. Najpierw musimy zająć się koncepcjami, a nie problemem, tak jak go postrzegasz, a w konsekwencji Twój problem zniknie.

automatycznie zwiększane identyfikatory, które są oczywiście kluczami podstawowymi.

Nie oni nie są. To powszechne nieporozumienie. I na pewno pojawią się problemy.

ID pole nie może być kluczem podstawowym w sensie angielskim, technicznym lub relacyjnym.

  • Jasne, w SQL możesz zadeklarować dowolne pole, które ma być PRIMARY KEY , ale to nie przekształca go w magiczny sposób w klucz podstawowy w sensie angielskim, technicznym lub relacyjnym. Możesz nazwać chihuahua „Rottweiller”, ale to nie zmienia go w Rottweillera, pozostaje chihuahua. Jak każdy język, SQL po prostu wykonuje polecenia, które mu podajesz, nie rozumie PRIMARY KEY aby oznaczać coś relacyjnego, po prostu uderza unikalny indeks w kolumnie (lub polu).

  • Problem polega na tym, że zadeklarowałeś ID być PRIMARY KEY , myślisz go jako klucz podstawowy i możesz spodziewać się że ma pewne cechy Klucza Pierwotnego. Z wyjątkiem niepowtarzalności identyfikatora wartość , nie zapewnia żadnych korzyści. Nie ma żadnych cech Klucza Pierwotnego ani żadnego Klucza Relacyjnego. Nie jest to klucz w sensie angielskim, technicznym czy relacyjnym. Deklarując, że nieklucz jest kluczem, tylko pomylisz się i dowiesz się, że coś jest strasznie nie tak, tylko wtedy, gdy użytkownik narzeka na duplikaty w tabeli.

Tabele relacyjne muszą mieć wiersz wyjątkowość

PRIMARY KEY na ID pole nie zawiera wiersza wyjątkowość. Dlatego nie jest to tabela relacyjna zawierająca wiersze, a jeśli tak nie jest, to jest to plik zawierający rekordy. Nie ma żadnej integralności ani mocy (na tym etapie będziesz świadomy tylko mocy łączenia) ani szybkości, jaką ma tabela w relacyjnej bazie danych.

Wykonaj ten kod (MS SQL 2008) i udowodnij to sobie. Proszę, nie czytaj po prostu tego i nie rozumiej, a następnie przejdź do reszty tej odpowiedzi, ten kod musi zostać wykonany przed dalszym czytaniem . Ma wartość leczniczą.

    CREATE TABLE dumb_file (
        id         INT      NOT NULL  IDENTITY  PRIMARY KEY,
        name_first CHAR(30) NOT NULL,
        name_last  CHAR(30) NOT NULL
        )

    INSERT dumb_file VALUES ( "Mickey", "Mouse" )  -- succeeds
    INSERT dumb_file VALUES ( "Mickey", "Mouse" )  -- succeeds, but not intended
    INSERT dumb_file VALUES ( "Mickey", "Mouse" )  -- succeeds, but not intended

    SELECT * FROM dumb_file

Zauważ, że masz zduplikowane wiersze . Tabele relacyjne muszą mieć unikalne wiersze . Kolejny dowód na to, że nie masz tabeli relacyjnej ani żadnej z jej cech.

Zauważ, że w Twoim raporcie jedyną unikatową rzeczą jest ID pole, na którym żaden użytkownik się nie przejmuje, żaden użytkownik nie widzi, bo to nie są dane, to jakieś dodatkowe bzdury, które jakiś bardzo głupi "nauczyciel" kazał ci wstawiać w każdym pliku. Masz rekord niepowtarzalność, ale nie wiersz wyjątkowość.

Jeśli chodzi o dane (prawdziwe dane bez dodatkowych dodatków), dane name_last i name_first może istnieć bez ID pole. Osoba ma imię i nazwisko bez wybitego dowodu tożsamości na czole.

Drugą rzeczą, której używasz, a która Cię dezorientuje, jest AUTOINCREMENT. Jeśli wdrażasz system archiwizacji rekordów bez funkcji relacyjnej, z pewnością jest to pomocne, nie musisz kodować przyrostu podczas wstawiania rekordów. Ale jeśli wdrażasz relacyjną bazę danych, nie ma to żadnego sensu, ponieważ nigdy jej nie użyjesz. W SQL jest wiele funkcji, których większość ludzi nigdy nie używa.

Działanie naprawcze

Jak więc uaktualnić, podnieść ten głupi_plik, który jest pełen zduplikowanych wierszy, do tabeli relacyjnej, aby uzyskać niektóre cechy i zalety tabeli relacyjnej? Są do tego trzy kroki.

  1. Musisz zrozumieć klawisze

    • A odkąd przeszliśmy od plików ISAM z lat 70. do Modelu relacyjnego , musisz zrozumieć klucze relacyjne . To znaczy, jeśli chcesz uzyskać korzyści (integralność, moc, szybkość) relacyjnej bazy danych.

    Dr E F Cood, w swoim RM , oświadczył, że:

    klucz składa się z danych

    i

    wiersze w tabeli muszą być niepowtarzalne

    Twój „klucz” nie składa się z danych. Jest to jakiś dodatkowy, nie będący pasożytem danych, spowodowany przez twoje zarażenie chorobą twojego „nauczyciela”. Rozpoznaj to jako takie i pozwól sobie na pełną zdolność umysłową, którą dał ci Bóg (zauważ, że nie proszę cię o myślenie w kategoriach odosobnionych, fragmentarycznych lub abstrakcyjnych, wszystkie elementy w bazie danych muszą być ze sobą zintegrowane). Stwórz prawdziwy klucz z danych i tylko z danych. W tym przypadku jest tylko jeden możliwy klucz:(name_last, name_first).

  2. Wypróbuj ten kod , deklaruj unikalne ograniczenie danych:

         CREATE TABLE dumb_table (
            id         INT      NOT NULL  IDENTITY  PRIMARY KEY,
            name_first CHAR(30) NOT NULL,
            name_last  CHAR(30) NOT NULL
    
            CONSTRAINT UK 
                UNIQUE ( name_last, name_first )
            )
    
        INSERT dumb_table VALUES ( "Mickey", "Mouse" )  -- succeeds
        INSERT dumb_table VALUES ( "Mickey", "Mouse" )  -- fails, as intended
        INSERT dumb_table VALUES ( "Minnie", "Mouse" )  -- succeeds
    
        SELECT * FROM dumb_table
    

    Teraz mamy unikalność wiersza . Taka jest sekwencja, która zdarza się większości ludzi:tworzą plik, który pozwala na duplikaty; nie mają pojęcia, dlaczego w listach rozwijanych pojawiają się duplikaty; użytkownik krzyczy; modyfikują plik i dodają indeks, aby zapobiec duplikatom; idą do następnej poprawki błędu. (Mogą to zrobić poprawnie lub nie, to już inna historia).

  3. Drugi poziom. Dla myślących ludzi, którzy myślą poza naprawami. Skoro mamy teraz unikalność wierszy, to co w imię Nieba jest celem ID pole, dlaczego w ogóle go mamy ??? Och, bo chihuahua nazywa się Rotty i boimy się go dotknąć.

    Deklaracja, że ​​jest to PRIMARY KEY jest fałszywe, ale pozostaje, powodując zamieszanie i fałszywe oczekiwania. Jedynym oryginalnym kluczem, jaki istnieje, jest (name_last, name_fist), i jest to klucz alternatywny w tym momencie.

    Dlatego ID pole jest całkowicie zbędne; podobnie jak indeks, który to obsługuje; podobnie jak głupie AUTOINCREMENT; podobnie jak fałszywa deklaracja, że ​​jest to PRIMARY KEY; a wszelkie oczekiwania co do tego są fałszywe.

    Dlatego usuń zbędne ID pole. Wypróbuj ten kod :

        CREATE TABLE honest_table (
            name_first CHAR(30) NOT NULL,
            name_last  CHAR(30) NOT NULL
    
            CONSTRAINT PK 
            PRIMARY KEY ( name_last, name_first )
            )
    
        INSERT honest_table VALUES ( "Mickey", "Mouse" )  -- succeeds
        INSERT honest_table VALUES ( "Mickey", "Mouse" )  -- fails, as intended
        INSERT honest_table VALUES ( "Minnie", "Mouse" )  -- succeeds
    
        SELECT * FROM honest_table
    

    Działa dobrze, działa zgodnie z przeznaczeniem, bez zbędnych pól i indeksów.

    Pamiętaj o tym i rób to dobrze za każdym razem.

Fałszywi nauczyciele

Zgodnie z radą, w tych czasach ostatecznych będziemy mieć ich wielu. Zwróć uwagę na „nauczycieli”, którzy propagują ID kolumny, dzięki szczegółowym dowodom w tym poście, po prostu nie rozumieją Modelu relacyjnego lub relacyjne bazy danych. Zwłaszcza ci, którzy piszą o tym książki.

Jak widać, utknęli w technologii ISAM sprzed 1970 roku. To wszystko, co rozumieją i to wszystko, czego mogą nauczyć. Używają kontenera bazy danych SQL, aby ułatwić dostęp, odzyskiwanie, tworzenie kopii zapasowych itp., ale zawartość jest czystym systemem archiwizacji rekordów bez integralności relacyjnej, mocy lub szybkości. AFAIC, to poważne oszustwo.

Oprócz ID pola, oczywiście jest kilka pozycji, które są kluczowymi pojęciami Relacja-albo-nie, które razem wzięte powodują, że dochodzę do tak poważnego wniosku. Te inne elementy są poza zakresem tego posta.

Jedna szczególna para idiotów przeprowadza obecnie atak na Pierwszą Normalną Formę. Należą do azylu.

Odpowiedź

A teraz reszta Twojego pytania.

Czy istnieje sposób, aby utworzyć relacyjną tabelę bez utraty funkcji automatycznego przyrostu?

To jest zdanie wewnętrznie sprzeczne. Ufam, że zrozumiesz moje wyjaśnienie, tabele relacyjne nie są potrzebne dla AUTOINCREMENT "funkcje"; jeśli plik ma AUTOINCREMENT , nie jest to tabela relacyjna.

AUTOINCREMENT jest dobre tylko z jednego powodu:jeśli i tylko wtedy, gdy chcesz utworzyć arkusz kalkulacyjny Excel w kontenerze bazy danych SQL, wypełniony polami o nazwie A, B, i C, na górze i zapisz liczby po lewej stronie. W kategoriach bazy danych jest to wynik SELECT, spłaszczony widok danych, czyli nie źródło danych, które są zorganizowane (znormalizowane).

Innym możliwym (ale nie preferowanym) rozwiązaniem może być inny klucz podstawowy w pierwszej tabeli, który jest nazwą użytkownika, oczywiście nie z instrukcją automatycznego przyrostu. Czy to nieuniknione?

W pracy technicznej nie dbamy o preferencje, bo to jest subiektywne i cały czas się zmienia. Dbamy o poprawność techniczną, bo to jest obiektywne i to się nie zmienia.

Tak, to nieuniknione. Bo to tylko kwestia czasu; liczba błędów; liczba „nie mogę zrobić”; wielu użytkowników krzyczy, aż staniesz twarzą w twarz z faktami, pokonasz fałszywe deklaracje i zdasz sobie sprawę, że:

  • jedyny sposób, aby upewnić się, że użytkownik wiersze są unikalne, że nazwy użytkowników są unikalne, jest zadeklarowanie UNIQUE ograniczenie na nim

  • i pozbądź się user_id lub id w pliku użytkownika

  • który promuje user_name na PRIMARY KEY

Tak, ponieważ cały twój problem z trzecim stołem, nieprzypadkowo, zostaje wyeliminowany.

Ta trzecia tabela to Tabela asocjacyjna . Jedyny wymagany klucz (klucz podstawowy) to połączenie dwóch nadrzędnych kluczy podstawowych. Zapewnia to niepowtarzalność wierszy , które są identyfikowane przez ich klucze, a nie przez ich IDs.

Ostrzegam Cię o tym, ponieważ ci sami „nauczyciele”, którzy nauczyli Cię błędu implementacji ID pola, naucz błąd implementacji ID pola w Tabeli Asocjacyjnej, gdzie podobnie jak w przypadku zwykłej tabeli jest ona zbędna, nie ma sensu, wprowadza duplikaty i powoduje zamieszanie. I jest to podwójnie zbędne, ponieważ dwa klucze, które zapewniają, już tam są, patrząc nam prosto w twarz.

Ponieważ nie rozumieją RM lub terminy relacyjne, nazywają tabele asocjacyjne tabelami „łącza” lub „map”. Jeśli mają ID pola, w rzeczywistości są to pliki.

Tabele przeglądowe

ID pola są szczególnie głupą rzeczą do zrobienia dla tabel przeglądowych lub referencyjnych. Większość z nich posiada rozpoznawalne kody, nie ma potrzeby wyliczania w nich listy kodów, ponieważ kody są (powinny być) niepowtarzalne.

Co więcej, posiadanie kodów w tabelach podrzędnych jako FKs, jest Dobrą Rzeczą:kod jest znacznie bardziej znaczący i często oszczędza niepotrzebne sprzężenie:

    SELECT ...
        FROM child_table           -- not the lookup table
        WHERE gender_code = "M"    -- FK in the child, PK in the lookup

zamiast:

    SELECT ...
        FROM child_table
        WHERE gender_id = 6        -- meaningless to the maintainer

lub gorzej:

    SELECT ...
        FROM child_table C         -- that you are trying to determine
        JOIN lookup_table L
            ON C.gender_id = L.gender_id
        WHERE L.gender_code = "M"  -- meaningful, known

Pamiętaj, że jest to coś, czego nie można uniknąć:potrzebujesz niepowtarzalności kodu wyszukiwania i wyjątkowość w opisie. To jedyna metoda zapobiegania duplikatom w każdej z dwóch kolumn:

    CREATE TABLE gender (
        gender_code  CHAR(2)  NOT NULL,
        name         CHAR(30) NOT NULL

        CONSTRAINT PK 
            PRIMARY KEY ( gender_code )

        CONSTRAINT AK 
            UNIQUE ( name )
        )

Pełny przykład

Na podstawie szczegółów w twoim pytaniu podejrzewam, że masz problemy ze składnią SQL i definicją FK, więc podam całe potrzebne rozwiązanie jako przykład (ponieważ nie podałeś definicji plików):

    CREATE TABLE user (                 -- Typical Identifying Table
        user_name  CHAR(16) NOT NULL,   -- Short PK
        name_first CHAR(30) NOT NULL,   -- Alt Key.1
        name_last  CHAR(30) NOT NULL,   -- Alt Key.2
        birth_date DATE     NOT NULL    -- Alt Key.3

        CONSTRAINT PK                   -- unique user_name
            PRIMARY KEY ( user_name )

        CONSTRAINT AK                   -- unique person identification
            PRIMARY KEY ( name_last, name_first, birth_date )
        )

    CREATE TABLE sport (                  -- Typical Lookup Table
        sport_code  CHAR(4)  NOT NULL,    -- PK Short code
        name        CHAR(30) NOT NULL     -- AK

        CONSTRAINT PK 
            PRIMARY KEY ( sport_code )

        CONSTRAINT AK 
            PRIMARY KEY ( name )
        )

    CREATE TABLE user_sport (           -- Typical Associative Table
        user_name  CHAR(16) NOT NULL,   -- PK.1, FK
        sport_code CHAR(4)  NOT NULL,   -- PK.2, FK
        start_date DATE     NOT NULL

        CONSTRAINT PK 
            PRIMARY KEY ( user_name, sport_code )

        CONSTRAINT user_plays_sport_fk
            FOREIGN KEY     ( user_name )
            REFERENCES user ( user_name )

        CONSTRAINT sport_occupies_user_fk
            FOREIGN KEY      ( sport_code )
            REFERENCES sport ( sport_code )
        )

Tam PRIMARY KEY deklaracja jest szczera, jest to klucz podstawowy; brak ID; nie AUTOINCREMENT; bez dodatkowych indeksów; brak zduplikowanych wierszy; brak błędnych oczekiwań; żadnych wynikających z tego problemów.

Model danych

Oto model danych z definicjami.

  • Przykładowy model danych sportowych użytkownika

  • Jeśli nie jesteś przyzwyczajony do notacji, pamiętaj, że każdy mały tik, wycięcie i oznaczenie, linia ciągła vs przerywana, kwadrat vs zaokrąglone rogi, oznacza coś bardzo konkretnego. Zapoznaj się z Zapis IDEF1X .

  • Obraz jest wart tysiąca słów; w tym przypadku standardowe zdjęcie reklamacyjne jest warte więcej; zły nie jest wart papieru, na którym jest narysowany.

  • Proszę dokładnie sprawdzić frazy czasownikowe, stanowią one zestaw predykatów. Pozostałą część predykatów można określić bezpośrednio z modelu. Jeśli nie jest to jasne, zapytaj.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wysyłanie zapytań do wielu baz danych jednocześnie

  2. Jak znaleźć lokalizację MySQL my.cnf?

  3. Jak obliczyć przychody w MySQL

  4. Przechowywanie plików w bazie danych Vs system plików

  5. Generowanie zakresu liczb w MySQL