3

Я разрабатываю приложение SaaS с многопользовательской лицензией, и я решил использовать единую БД (MySQL Innodb на данный момент) для данных клиента. Я решил использовать составные первичные ключи, такие как PK (client_id, id). У меня есть 2 способа здесь,Композитные первичные ключи и автоинкремент? Что такое хорошая практика?

1: инкремент "ИД" от себя (от триггера или из кода)

или

2: Make "ID" в качестве автоприращение по MySQL.

В первом случае я буду иметь уникальный идентификаторам для каждого клиента, поэтому каждый клиент будет иметь идентификатор 1, 2, 3 и т.д. .. Во втором случае идентификатор будет расти для всех клиентов. Какова наилучшая практика здесь? Мои приоритеты: производительность, безопасность & масштабирование. Благодаря!

+1

Первый вариант действительно не дает вам многого и должен поддерживаться. Будет ли эта новая таблица иметь отношение 1-много с клиентской таблицей? Что на самом деле делает запись отличной? Если ничего нет, используйте автоинкремент. Это действительно зависит от ситуации. – sgeddes

+1

В качестве последующего комментария к последнему комментарию, является ли клиент_id внешним ключом? То есть он ссылается на существующий идентификатор в таблице клиентов? –

+1

Ваш первичный ключ должен быть только автоинкрементным идентификатором. Не включайте client_id, он не добавляет дополнительной информации.PK (client_id, id) с идентификатором auto_increment для innodb возможен только при добавлении индекса (id), который также не добавит дополнительной информации. И PK (client_id, id) с самоподдерживающимися идентификаторами увеличит накладные расходы, а также не добавит дополнительной информации (например, вы не хотите проверять новую вставку данных путем тестирования, если идентификатор уже существует для обеспечения целостности данных), если вы добавите новая строка, вы просто увеличите id независимо от того, что). Итак: PK (id) и индекс (Клиент). – Solarflare

ответ

2

Вы обязательно хотите использовать автоинкрементные значения id как первичные ключи. Для этого существует много причин. Вот некоторые.

  1. Избегание условий гонки (случайный id дублирование) требует особой осторожности, если вы сами их создаете. Потратьте эту умственную энергию - развитие, QA, операции - на то, чтобы сделать ваш SaaS превосходным, а не изобретать плоскую шину на первичных ключах.
  2. Вы все же можете поместить индекс на (client_id, id), даже если это не ПК.
  3. Ваши операции JOIN будут проще в написании, тестировании и обслуживании.
  4. Этот шаблон запроса отлично подходит для получения последней строки для каждого клиента из таблицы. Он работает очень хорошо. Труднее делать такие вещи, если вы создаете свои собственные pks.

    SELECT t.* 
         FROM table t 
         JOIN (SELECT MAX(id) id 
           FROM table 
          GROUP BY client_id 
         ) m ON t.id = m.id 
    
+0

Я просто подумал, что составной ключ предоставит мне некоторую защиту (защищенную от ошибок с ошибками «id» и т. Д.) При выборе между данными клиентов и, возможно, некоторых масштабирующих (затененных) профи в будущем. Но похоже, что я просто усложняю вещи!) – teMkaa

1

"PK (client_id, идентификатор)" -

id INT UNSIGNED NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(client_id, id), 
INDEX(id) 

Да, эта комбинация будет работать. И он будет работать эффективно. Он не будет назначать 1,2,3 каждому клиенту, но это не имеет значения. Вместо этого последовательные идентификаторы будут разбросаны среди клиентов.

Возможно, что все ваши запросы будут включать WHERE client_id = (constant), правильно? Это означает, что PRIMARY KEY(client_id, id) всегда будет использоваться, и INDEX(id) не будет использоваться, кроме как для удовлетворения AUTO_INCREMENT.

Кроме того, этот ПК будет более эффективным, чем INDEX(client_id, id). (Это связано с тем, что InnoDB «кластеризует» ПК с данными.)

Смежные вопросы