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

SQL:Създаване на релационна таблица с 2 различни auto_increment

Концепции

Вие сте разбрали погрешно някои основни понятия и трудностите произтичат от това. Първо трябва да разгледаме концепциите, а не проблема, както го възприемате, и следователно проблемът ви ще изчезне.

автоматично увеличени идентификатори, които разбира се са първични ключове.

Не, не са. Това е често срещано погрешно схващане. И проблемите гарантирано ще последват.

ID полето не може да бъде първичен ключ в английския или технически или релационен смисъл.

  • Разбира се, в SQL можете да декларирате всеки поле да бъде PRIMARY KEY , но това не го превръща магически в първичен ключ в английския, технически или релационен смисъл. Можете да наречете чихуахуа "ротвайлер", но това не го превръща в ротвайлер, а остава чихуахуа. Както всеки език, SQL просто изпълнява командите, които му давате, той не разбира PRIMARY KEY за да означава нещо релационно, просто удря уникален индекс върху колоната (или полето).

  • Проблемът е, че сте декларирали ID да бъде PRIMARY KEY , мислите от него като първичен ключ и може да очаквате че притежава някои от качествата на първичен ключ. С изключение на уникалността на стойността на ID , не носи никаква полза. Той няма нито едно от качествата на първичен ключ или какъвто и да е релационен ключ по този въпрос. Това не е Ключ в английския, технически или релационен смисъл. Като декларирате не-ключ за ключ, вие само ще се объркате и ще разберете, че има нещо ужасно нередно, само когато потребителят се оплаква от дубликати в таблицата.

Релационните таблици трябва да имат ред уникалност

PRIMARY KEY на ID полето не предоставя ред уникалност. Следователно това не е релационна таблица, съдържаща редове, и ако не е това, тогава това е файл, съдържащ записи. Тя няма нито цялост, нито мощност (на този етап ще сте наясно само със силата на присъединяване) или скорост, която има таблица в релационна база данни.

Изпълнете този код (MS SQL 2008) и го докажете на себе си. Моля, не просто четете това и го разбирайте, а след това продължете да четете останалата част от този отговор, този код трябва да бъде изпълнен, преди да прочетете по-нататък . Има лечебна стойност.

    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

Забележете, че имате дублиращи се редове . Релационните таблици трябва да имат уникални редове . Още едно доказателство, че нямате релационна таблица или някое от качествата на такава.

Обърнете внимание, че във вашия отчет единственото нещо, което е уникално, е ID поле, за което никой потребител не се интересува, никой потребител не вижда, защото това не са данни, това е някаква допълнителна глупост, която някой много глупав "учител" ви каза да поставите във всеки файл. Имате запис уникалност, но не и ред уникалност.

По отношение на данните (реалните данни минус външните добавки), данните name_last и name_first може да съществува без ID поле. Човек има собствено и фамилно име без лична карта на челото му.

Второто нещо, което използвате, което ви обърква, е AUTOINCREMENT. Ако внедрявате система за архивиране на записи без релационни възможности, разбира се, това е полезно, не е нужно да кодирате увеличението, когато вмъквате записи. Но ако внедрявате релационна база данни, тя няма никаква цел, защото никога няма да я използвате. Има много функции в SQL, които повечето хора никога не използват.

Коригиращи действия

И така, как да надстроите, издигнете този dumb_file, който е пълен с дублиращи се редове, до релационна таблица, за да получите някои от качествата и предимствата на релационна таблица? Има три стъпки към това.

  1. Трябва да разбирате Ключове

    • И тъй като преминахме от ISAM файлове от 1970-те до Релационния модел , трябва да разберете Релационни ключове . Тоест, ако искате да получите предимствата (целостта, мощността, скоростта) на релационна база данни.

    Д-р E F Cood, в неговия RM , декларира, че:

    от данните се съставя ключ

    и

    редовете в таблицата трябва да са уникални

    Вашият "ключ" не е съставен от данните. Това е някакъв допълнителен паразит без данни, причинен от това, че сте заразени с болестта на вашия "учител". Признайте го като такъв и си позволете пълния умствен капацитет, който Бог ви е дал (забележете, че не ви моля да мислите в изолирани или фрагментирани или абстрактни термини, всички елементи в базата данни трябва да бъдат интегрирани един с друг). Съставете истински ключ от данните и само от данните. В този случай има само един възможен ключ:(name_last, name_first).

  2. Изпробвайте този код , декларира уникално ограничение за данните:

         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
    

    Сега имаме уникалност на редове . Това е последователността, която се случва на повечето хора:те създават файл, който позволява измамвания; те нямат представа защо в падащите менюта се появяват измамници; потребителят крещи; те настройват файла и добавят индекс, за да предотвратят измамите; те преминават към следващото корекция на грешки. (Може да го направят правилно или не, това е друга история.)

  3. Второто ниво. За мислещи хора, които мислят отвъд поправката. Тъй като вече имаме уникалност на редовете, това, за бога, е целта на ID поле, защо изобщо го имаме??? О, защото чихуахуа се казва Роти и се страхуваме да го докоснем.

    Декларацията, че е PRIMARY KEY е невярно, но остава, причинявайки объркване и фалшиви очаквания. Единственият истински ключ, който има, е (name_last, name_fist), и това е алтернативен ключ в този момент.

    Следователно ID полето е напълно излишно; както и индексът, който го поддържа; както и глупавото AUTOINCREMENT; както и фалшивата декларация, че това е PRIMARY KEY; и всички очаквания, които може да имате от него, са фалшиви.

    Затова премахнете излишния ID поле. Изпробвайте този код :

        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
    

    Работи добре, работи по предназначение, без външни полета и индекси.

    Моля, запомнете това и го правете правилно всеки път.

Лъжеучители

В тези последни времена, както ни съветваме, ще имаме много от тях. Забележете добре „учителите“, които разпространяват ID колони, по силата на подробните доказателства в тази публикация, просто не разбират Релационния модел или Релационни бази данни. Особено тези, които пишат книги за това.

Както е видно, те са заседнали в технологията ISAM преди 1970 г. Това е всичко, което разбират и това е всичко, на което могат да научат. Те използват контейнер на база данни SQL за улесняване на достъпа, възстановяване, архивиране и т.н., но съдържанието е чиста система за архивиране на записи без релационна цялост, мощност или скорост. AFAIC, това е сериозна измама.

В допълнение към ID полета, разбира се, има няколко елемента, които са ключови концепции за отношение или не, които взети заедно, ме карат да направя толкова сериозно заключение. Тези други елементи са извън обхвата на тази публикация.

Една конкретна двойка идиоти в момента организира атака срещу Първа нормална форма. Те принадлежат на убежището.

Отговор

Сега за останалата част от вашия въпрос.

Има ли начин да създам релационна таблица, без да губя функции за автоматично увеличение?

Това е самопротиворечащо изречение. Вярвам, че ще разберете от моето обяснение, релационните таблици нямат нужда за AUTOINCREMENT "Характеристика"; ако файлът има AUTOINCREMENT , това не е релационна таблица.

AUTOINCREMENT е добро само за едно нещо:ако и само ако искате да създадете електронна таблица на Excel в контейнера на база данни на SQL, пълна с полета с име A, B, и C, в горната част и запишете числа надолу от лявата страна. От гледна точка на базата данни, това е резултатът на SELECT, изравнен изглед на данните, който не източникът на данни, които са организирани (нормализирани).

Друго възможно (но не предпочитано) решение може да е, че има друг първичен ключ в първата таблица, което е потребителското име на потребителя, а не с израз за автоматично увеличение, разбира се. Неизбежно ли е?

В техническата работа не се интересуваме от предпочитанията, защото това е субективно и се променя непрекъснато. Ние се грижим за техническата коректност, защото това е обективно и не се променя.

Да, неизбежно е. Защото това е просто въпрос на време; брой бъгове; брой на "не мога да направя"; брой потребителски писъци, докато не се сблъскате с фактите, преодолеете фалшивите си декларации и осъзнаете, че:

  • единственият начин да се гарантира, че потребителят редове са уникални, че потребителските_имена са уникални, е да се декларира UNIQUE ограничение върху него

  • и се отървете от user_id или id в потребителския файл

  • който популяризира user_name към PRIMARY KEY

Да, защото целият ви проблем с третата таблица, неслучайно, след това е елиминиран.

Тази трета таблица е Асоциативна таблица . Единственият необходим ключ (първичен ключ) е съставен от двата родителски първични ключа. Това гарантира уникалност на редовете , които се идентифицират с техните ключове, а не с техните IDs.

Предупреждавам ви за това, защото същите „учители“, които ви научиха на грешката при внедряване на ID полета, научи грешката при внедряване на ID полета в асоциативната таблица, където, както при обикновената таблица, тя е излишна, не служи за цел, въвежда дубликати и предизвиква объркване. И е двойно излишно, защото двата ключа, които предоставят, вече са там и ни гледат в лицето.

Тъй като не разбират RM , или релационни термини, те наричат ​​асоциативни таблици "връзки" или "карта" таблици. Ако имат ID поле, те всъщност са файлове.

Таблици за справка

ID полетата са особено Глупави неща за правене за справочни или справочни таблици. Повечето от тях имат разпознаваеми кодове, няма нужда да изброявате списъка с кодове в тях, защото кодовете са (трябва да са) уникални.

Освен това, наличието на кодове в дъщерните таблици като FK е добро нещо:кодът е много по-смислен и често спестява ненужно присъединяване:

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

вместо:

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

или по-лошо:

    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

Имайте предвид, че това е нещо, което човек не може да избегне:имате нужда от уникалност на кода за търсене и уникалност на описанието. Това е единственият метод за предотвратяване на дублиране във всеки от двете колони:

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

        CONSTRAINT PK 
            PRIMARY KEY ( gender_code )

        CONSTRAINT AK 
            UNIQUE ( name )
        )

Пълен пример

От подробностите във вашия въпрос подозирам, че имате проблеми със синтаксиса на SQL и дефиницията на FK, така че ще дам цялото необходимо решение като пример (тъй като не сте дали дефиниции на файлове):

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

Там PRIMARY KEY декларацията е честна, тя е първичен ключ; няма ID; не AUTOINCREMENT; без допълнителни индекси; без дублиращи се редове; без погрешни очаквания; без последващи проблеми.

Модел на данни

Ето модела на данни, който да върви с дефинициите.

  • Примерен модел на потребителски спортни данни

  • Ако не сте свикнали с нотацията, моля, имайте предвид, че всяка малка отметка, прорез и знак, плътни срещу пунктирани линии, квадрат срещу заоблени ъгли, означава нещо много конкретно. Обърнете се към нотация IDEF1X .

  • Една картина струва хиляда думи; в този случай картината със стандартна жалба струва повече от това; лошият не си струва хартията, върху който е нарисуван.

  • Моля, проверете внимателно глаголните фрази, те включват набор от предикати. Останалата част от предикатите може да се определи директно от модела. Ако това не е ясно, моля, попитайте.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Производителност на MySQL:MyISAM срещу InnoDB

  2. Как да инсталирате и конфигурирате phpMyAdmin на Debian 8

  3. Как да задам часовата зона на MySQL?

  4. Как да създам последователност в MySQL?

  5. MySQL търсене и замяна на текст в поле