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
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.
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ą.
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.
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.
Jeśli się nie mylę, ograniczenia wymagają indeksów, więc podczas tworzenia, na przykład, ograniczenie klucza obcego MySQL automatycznie tworzy indeks.
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.
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