MySQL первичный ключ, который я никогда не выбираю - PullRequest
0 голосов
/ 30 января 2019

Довольно часто я сталкиваюсь с такой ситуацией:

table `user_adress`
+----------+-------------+--------------+---------+
|adress_id | user_id     | adress_type  |adress   |
+----------+-------------+--------------+---------+
|        1 |           1 | home         |adressXXX|
|        2 |           2 | home         |adressXXX|
|        3 |           3 | home         |adressXXX|
|        4 |           1 | work         |adressXXX|
|        5 |           2 | work         |adressXXX|
|        6 |           1 | second_home  |adressXXX|
+----------+-------------+--------------+---------+

Если я хочу использовать это, я использую такие запросы:

SELECT `adress` FROM `user_adress` WHERE `user_id`=1;

Кажется вполне нормальным, ноДело в том, что я использую «бесполезный» столбец adress_id, который не имеет никакой другой цели, кроме как быть первичным ключом с автоинкрементом только ради наличия первичного ключа в таблице MySQL.Я никогда не использую или не нуждаюсь в этом номере.Поэтому я понял, что вообще не должен использовать первичный ключ в своей таблице, полностью удалить adress_id и установить INDEX (без unique) в столбце user_id.Кажется, это хорошо - или я не прав?

У меня есть некоторые сомнения, потому что, сколько бы я ни читал, везде, где я вижу советы, в каждой таблице должен быть или даже нужен первичный ключ.Но почему?Возможно, моя база данных будет плохо спроектирована, если я позволю этому случиться, но, глядя на мою чрезвычайно простую таблицу примеров - я не могу представить, как это может быть в любой ситуации, особенно в таких простых случаях.Я не совсем правильно понял некоторые простые, основные правила создания таблиц и их правильной индексации - где дыра в моих задачах?

Ответы [ 3 ]

0 голосов
/ 30 января 2019

Чисто исходя из структуры вашей таблицы, я бы сказал, что ваш первичный ключ неверен.

Вместо этого, похоже, что ваш первичный ключ должен быть:

PRIMARY KEY (user_id, address_type)

Вы правы, что каждыйВ идеале таблица должна иметь первичный ключ, но первичные ключи могут содержать более несколько полей.

Иногда все еще проще иметь простой автоинкрементный идентификатор в качестве первичного ключа.Механизм хранения Innodb фактически сделает это тайно в невидимом поле.

Возможно, в вашем ограниченном примере это не нужно, но во многих реальных случаях это может просто упростить работу с данными.В этом смысле я бы сказал, что использование искусственного автоинкрементного первичного ключа не является наилучшей практикой с академической точки зрения, но может быть хорошей идеей с точки зрения «реального мира, работы и администрирования MySQL».

Есть также системы ORM, которые просто требуют этого (как бы плохо).

0 голосов
/ 31 января 2019

Это правда, что таблице реляционной базы данных нужен первичный ключ.

Но все сводится к определению первичного ключа.Первичный ключ НЕ обязательно является одним целочисленным столбцом, который автоматически увеличивается.

Первичный ключ - это любой столбец или набор из нескольких столбцов, которые могут однозначно идентифицировать каждую строку.В вашем случае комбинация user_id и address_type может сделать это (как уже было опубликовано Evert).

Так что если вы сделаете вашу таблицу такой:

CREATE TABLE user_address (
  user_id INT NOT NULL,
  address_type varchar(10) NOT NULL,
  address TEXT NOT NULL,
  PRIMARY KEY (user_id, address_type)
);

Тогда выможет обновлять или удалять одну конкретную строку за раз, например, так:

UPDATE user_address SET ...
WHERE user_id = ? AND address_type = ?;

Некоторые люди считают, что удобнее применять соглашение о том, что каждая таблица должна иметь один целочисленный столбец в качестве первичного ключа.Они даже могут настаивать на том, что столбец должен называться id для согласованности.

В последовательности есть какое-то преимущество, но, с другой стороны, безрассудно настаивать на таком соглашении, даже если оно бесполезно.

0 голосов
/ 30 января 2019

Как видно из ваших данных, первичный ключ обеспечивает прямой доступ к одной строке без каких-либо проблем или двусмысленностей ... (особенно для удаления или обновления)

это именно цель первичного ключа..

тот факт, что вам может понадобиться присоединить эту таблицу к таблице других пользователей по user_id

, а индекс (не уникальный) для user_id

create index  myidx on mytable(user_id)

действительно полезен для более быстрого объединенияразрешить прямой доступ только в строках, связанных с одним user_id

...