MySQL terminologia "ograniczenia" vs "klucze obce" różnica?

Patrzę na dokumenty MySQL Tutaj i próbuję uporządkować rozróżnienie między kluczami obcymi a ograniczeniami. Myślałem, że FK był ograniczeniem, ale lekarze mówią o nich, jakby to były oddzielne rzeczy.

Składnia tworzenia FK jest (częściowo)...

[CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)

Więc klauzula "CONSTRAINT" jest opcjonalna. Dlaczego miałbyś to uwzględnić,czy nie? Jeśli to pominiesz, czy MySQL utworzy klucz obcy, ale nie ograniczenie? A może bardziej jak "CONSTRAINT" to nic innego jak nazwa dla Ciebie FK, więc jeśli nie podasz to dostaniesz anonimowy FK?

Każde Wyjaśnienie byłoby bardzo mile widziane.

Dzięki,

Ethan

Author: Bill Karwin, 2008-11-22

6 answers

Tak, klucz obcy jest rodzajem ograniczenia. MySQL ma nierównomierne wsparcie dla ograniczeń:

  • PRIMARY KEY: tak jako ograniczenie tabeli i ograniczenie kolumny.
  • FOREIGN KEY: tak jako ograniczenie tabeli, ale tylko z silnikami przechowywania InnoDB i BDB; w przeciwnym razie przetwarzane, ale ignorowane.
  • CHECK: parsed but ignored in all storage engines.
  • UNIQUE: tak jako ograniczenie tabeli i ograniczenie kolumny.
  • NOT NULL: tak jako ograniczenie kolumny.
  • I inni atrybuty ograniczenia: brak wsparcia.

Klauzula CONSTRAINT pozwala na jawne nazwanie ograniczenia, aby metadane były bardziej czytelne lub aby użyć nazwy, gdy chcesz zrezygnować z ograniczenia. Standard SQL wymaga, aby klauzula CONSTRAINT Była opcjonalna. Jeśli go pominiesz, RDBMS utworzy nazwę automatycznie, a nazwa zależy od implementacji.

 58
Author: Bill Karwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-21 23:58:04

Ogólnie (nie jest to konieczne MySQL), klucze obce są ograniczeniami, ale ograniczenia nie zawsze są kluczami obcymi. Pomyśl o podstawowych ograniczeniach kluczowych, unikalnych ograniczeniach itp.

Wracając do konkretnego pytania, masz rację, pomijając część CONSTRAINT [symbol] utworzy FK Z automatycznie wygenerowaną nazwą.

 9
Author: Dan C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-22 00:01:51

Obecnie nasze DDL do tabeli CREATE mają ten format-zwróć uwagę na unikalny klucz i składnię definicji klucza obcego, której użyliśmy.

CREATE TABLE my_dbschema.my_table (
    id INT unsigned auto_increment PRIMARY KEY,
    account_nbr INT NOT NULL,
    account_name VARCHAR(50) NOT NULL,
    active_flg CHAR(1) NOT NULL DEFAULT 'Y',
    vendor_nbr INT NOT NULL,
    create_ts TIMESTAMP NOT NULL DEFAULT current_timestamp,
    create_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    last_upd_ts TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp,
    last_upd_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    UNIQUE KEY uk1_my_table(account_nbr, account_name),
    FOREIGN KEY fk1_my_table(vendor_nbr) REFERENCES vendor(vendor_nbr)
    );

W tym formacie MySQL automatycznie tworzy INDEX-es o nazwach uk1_my_table i fk1_my_table; ale nazwa obiektu FK jest czymś innym-my_table_ibfk_1 (tj. tablename_ibfk_N-zdefiniowany system). Więc ALTER TABLE my_table DROP FOREIGN KEY fk1_my_table nie zadziała (a co za tym idzie frustrujące i budzące alarmy), ponieważ nie ma obiektu FK db o takiej nazwie.

Oto alternatywa Format DDL wrt the constarints (Ref: https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html) :-

CREATE TABLE my_dbschema.my_table (
    id INT unsigned auto_increment PRIMARY KEY,
    account_nbr INT NOT NULL,
    account_name VARCHAR(50) NOT NULL,
    active_flg CHAR(1) NOT NULL DEFAULT 'Y',
    vendor_nbr INT NOT NULL,
    create_ts TIMESTAMP NOT NULL DEFAULT current_timestamp,
    create_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    last_upd_ts TIMESTAMP NOT NULL DEFAULT current_timestamp ON UPDATE current_timestamp,
    last_upd_usr_id VARCHAR(10) NOT NULL DEFAULT 'DFLTUSR',
    CONSTRAINT uk1_my_table UNIQUE KEY (account_nbr, account_name),
    CONSTRAINT fk1_my_table FOREIGN KEY (vendor_nbr) REFERENCES vendor(vendor_nbr)
    );

W tym formacie MySQL nadal tworzy INDEX-es o nazwach uk1_my_table i fk1_my_table automatycznie, ale nazwa obiektu FK nie jest czymś innym – jest to fk1_my_table, jak wspomniano w DDL. Więc ALTER TABLE my_table DROP FOREIGN KEY fk1_my_table działa, ale zostawia za sobą indeks imienników.

I zauważ, że ALTER TABLE my_table DROP INDEX fk1_my_table początkowo nie będzie działać (gdy FK nie jest jeszcze upuszczony), z komunikat o błędzie, że jest on używany w FK! Jeśli polecenie Drop FK zostało wykonane pomyślnie, tylko wtedy działa indeks DROP.

Nadzieję, że to wyjaśnia i pomaga rozwiązać zamieszanie.

 2
Author: RxBx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-15 20:33:39

Nie mogę odpowiedzieć na MySQL, ale to są ograniczenia. Wszystko, co zmusza dane do pewnego stanu, jest ograniczeniem. Istnieje kilka rodzajów ograniczeń, unikalny, klucz podstawowy, czek i klucze obce są ograniczeniami. Może MySQL ma inne.

Czasami słowa są dozwolone w poleceniach, ale nie są wymagane dla czytelności, tak jak FROM w instrukcji DELETE.

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-21 23:47:45

Jeśli się nie mylę, ograniczenia wymagają indeksów, więc podczas tworzenia, na przykład, ograniczenie klucza obcego MySQL automatycznie tworzy indeks.

 1
Author: Mario Juárez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-25 19:04:31

To chyba najbardziej zagmatwany top w MySQL.

Wiele osób mówi, że na przykład 'klucz podstawowy', 'klucz obcy' i 'klucz unikalny' są w rzeczywistości indeksami! (Oficjalna dokumentacja MySQL znajduje się tutaj)

Wielu innych z kolei twierdzi, że są to raczej ograniczenia (co ma sens, bo kiedy ich używasz, naprawdę nakładasz ograniczenia na dotknięte kolumny).

Jeśli naprawdę są indeksami, to po co używać ograniczenie w celu nadania mu nazwy, skoro przy jego tworzeniu powinieneś móc używać nazwy tego indeksu?

Przykład:

... Klucz obcy index_name (col_name1, col_name2, ...)

Jeśli klucz obcy jest indeksem, wtedy powinniśmy być w stanie użyć index_name do obsługi GO. Jednak nie możemy.

Ale jeśli nie są to indeksy, ale rzeczywiste kontrasty, które używają indeksów do działania, to ma to sens.

W każdym razie, nie wiemy. Właściwie nikt nie wie.

 0
Author: Johann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-11 23:00:19