Ponieważ muszą być unikalne, jak nazwać FK w bazie danych MySQL?
Odpowiedzi:
W MySQL nie ma potrzeby nadawania nazwy symbolicznej ograniczeniom klucza obcego. Jeśli nazwa nie zostanie podana, InnoDB automatycznie utworzy unikalną nazwę.
W każdym razie jest to konwencja, której używam:
fk_[referencing table name]_[referenced table name]_[referencing field name]
Przykład:
CREATE TABLE users(
user_id int,
name varchar(100)
);
CREATE TABLE messages(
message_id int,
user_id int
);
ALTER TABLE messages ADD CONSTRAINT fk_messages_users_user_id
FOREIGN KEY (user_id) REFERENCES users(user_id);
Staram się trzymać tych samych nazw pól przy odwoływaniu się i przywoływanych tabelach, jak w user_id
powyższym przykładzie. Jeśli nie jest to praktyczne, dołączam również nazwę pola, do którego się odwołujemy, do nazwy klucza obcego.
Ta konwencja nazewnictwa pozwala mi „odgadnąć” nazwę symboliczną po prostu patrząc na definicje tabeli, a ponadto gwarantuje również unikalne nazwy.
member_id
~> łącze do członka tabeli, edited_id
~> klucz obcy dla edytowanego użytkownika, również łącze do członka tabeli. Jak mam je nazwać?
mój wybór jest inny. moim zdaniem tablica powinna mieć id
pole, a nie user_id
jedno, bo tablica właśnie się nazywa user
, więc:
CREATE TABLE users(
id int,
name varchar(100)
);
CREATE TABLE messages(
id int,
user_id int
);
user_id
w messages
tabeli jest polem fk, więc musi jasno określić, który identyfikator to ( user_id
).
w pełni zrozumiałą konwencją nazewnictwa, moim zdaniem, mogłaby być:
fk_[referencing table name]_[referencing field name]_[referenced table name]_[referenced field name]
i.e.: `fk_messages_user_id_users_id`
Uwaga:
ten fk może być unikalny, ponieważ jeśli messages_user
istnieje tabela, nazwa pola odniesienia powinna być user_id
(a nie tylko id
), a nazwa fk powinna być:
fk_messages_user_user_id_users_id
innymi słowy, konwencja nazewnictwa kluczy obcych zapewnia unikalne nazwy, jeśli również używasz konwencji nazewnictwa „pole odniesienia / pole odniesienia” (i oczywiście możesz wybrać własną).
$id
gdzieś zmienną, nie mając pojęcia, do której tabeli należy. Im starszy jest Twój kod i im więcej osób nad nim pracowało, tym bardziej prawdopodobne jest to.
Jeśli nie odnosisz się do plików fk tak często po ich utworzeniu, jedną z opcji jest uproszczenie i pozwolenie MySQL na wykonanie nazewnictwa za Ciebie (jak Daniel Vassallo wspomina na początku swojej odpowiedzi ).
Chociaż nie będziesz w stanie jednoznacznie „odgadnąć” nazw ograniczeń za pomocą tej metody - możesz łatwo znaleźć nazwę ograniczenia klucza obcego, uruchamiając zapytanie:
use information_schema;
select TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME from KEY_COLUMN_USAGE where REFERENCED_TABLE_SCHEMA = 'your_db_schema_name' ORDER BY TABLE_NAME;
Na przykład możesz otrzymać następujące zapytanie z zapytania:
+------------+-------------+-----------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+------------+-------------+-----------------+-----------------------+------------------------+
| note | taskid | note_ibfk_2 | task | id |
| note | userid | note_ibfk_1 | user | id |
| task | userid | task_ibfk_1 | user | id |
+------------+-------------+-----------------+-----------------------+------------------------+
Jeśli ten dodatkowy krok nie jest dla ciebie zbyt duży, powinieneś być w stanie łatwo znaleźć fk, którego szukasz.
fk-[referencing_table]-[referencing_field]
Powodem jest połączenie referencing_table
i referencing_field
jest unikalne w bazie danych. W ten sposób nazwa klucza obcego będzie łatwa do odczytania, na przykład:
table `user`:
id
name
role
table `article`:
id
content
created_user_id /* --> user.id */
reviewed_user_id /* --> user.id */
Mamy więc dwa klucze obce:
fk-article-created_user_id
fk-article-reviewed_user_id
Dodawanie user
nazwy tabeli do nazwy klucza obcego jest zbędne.
user_role
? user
i role
ma relację manytomany i user_role
jest tabelą zawierającą cały klucz obcy. Powinien być fk_user_role_role
?