LINUX.ORG.RU
ФорумAdmin

Ключи MySQL

 


0

1
CREATE TABLE `extensions` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `context` varchar(40) NOT NULL,
  `exten` varchar(40) NOT NULL,
  `priority` int(11) NOT NULL,
  `app` varchar(40) NOT NULL,
  `appdata` varchar(256) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `cont` (`id`,`context`,`exten`,`priority`),
) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=latin1
CREATE TABLE `extensions` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `context` varchar(40) NOT NULL,
  `exten` varchar(40) NOT NULL,
  `priority` int(11) NOT NULL,
  `app` varchar(40) NOT NULL,
  `appdata` varchar(256) NOT NULL,
  PRIMARY KEY (`id`,`context`,`exten`,`priority`),
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=latin1

Какой вариант установки индексов более «правильный»?

не понятно, если есть индексы
KEY `exten` (`exten`),
KEY `context` (`context`)
то почему их нету в варианте 2?

не помню уже где, но где-то читал что если innodb то всегда дублируется первичный ключ для индекса, т.е. хранится будет

 PRIMARY KEY (`id`),
  UNIQUE KEY `cont` (/*id*/, `id`,`context`,`exten`,`priority`),
  KEY `exten` (/*id*/, `exten`),
  KEY `context` (/*id*/, `context`)

поэтому всегда нужно стремиться выбирать первичный индекс как можно легковесней

kiotoze ★★★★ ()

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

А так, в принципе, до одного места, особой разницы быть не должно, если у тебя не какие-нибудь index-organised table или еще какой изврат. Первый вариант более логичен. Во втором также отсутствуют индексы по exten и context, я полагаю они тебе были зачем-то нужны. Еще можно сказать, что такая комбинация ключей - primary key id, unique key id, x, y, z - наводит на мысли, что схема таки спроектирована неправильно.

alex_the_v ★★★ ()
Ответ на: комментарий от kiotoze

если innodb то всегда дублируется первичный ключ для индекса

Ты прав:

In InnoDB, each record in a secondary index contains the primary key columns for the row, as well as the columns specified for the secondary index
: https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html

Аргумент за то, чтобы выбирать primary key покомпактней.

alex_the_v ★★★ ()

Присоединяюсь к alex_the_v к части комбинации ключей. При PRIMARY KEY (`id`) и UNIQUE KEY `cont` (`id`,`context`,`exten`,`priority`) абсолютно любая комбинация `context`,`exten`,`priority` будет рассматриваться как уникальная. Т.е. в целом как первый так и второй вариант можно назвать заведомо «не правильным».

anc ★★★★★ ()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от alex_the_v

Аргумент за то, чтобы выбирать primary key покомпактней.

Да, PK выбирают компактней, по совсем не по причине конкретной реализации в отдельно взятой субд. Даже если бы такого не было, получается что все ссылающиеся таблицы должны содержать перечень полей указанный в PK. Для примера: есть две таблицы t1 (PK из 4-х полей) и t2, t2 содержит FK ссылающийся на PK t1 т.е. тоже содержит 4 поля из t1. Теперь представим что в t1 100 записей а вот в t2 100000 т.е. значения 4-х полей записаны 100000 раз. А если посмотреть на пример ТС так он туда еще два поля с varchar(40) приписал, получается ооочень не слабый оверхед.
Вообще говоря PK из большого кол-ва полей как бы намекает на то что БД спроектирована не правильно. Наверняка бывают исключения из правил, но я представить такого не могу и в своей практике не встречал.

anc ★★★★★ ()
Ответ на: комментарий от anc

PK надо выбирать компактней по множеству причин. Однако если посмотреть шире, то все эти сущности - таблицы, поля, ключи - это реализация некоей модели представления данных. А эта модель, в свою очередь, отражает какие-то сущности реального мира, и если у тебя комбинация x, y и z в реальном мире уникальна, то придется делать или PK или UNIQUE по ним, никуда не денешься (исключение - когда ты действительно уперся в производительность и выжимаешь последнее).

А вообще, я просто выразился немного неточно, надо было: «еще один аргумент за то, чтобы выбирать PK покомпактней»

alex_the_v ★★★ ()
Ответ на: комментарий от alex_the_v

А эта модель, в свою очередь, отражает какие-то сущности реального мира, и если у тебя комбинация x, y и z в реальном мире уникальна, то придется делать или PK или UNIQUE по ним, никуда не денешься

1. Ну уж не текстовые поля же включать.
2. Совсем не обязательно особенно в части PK btw один из «ЗА» за использование суррогатных PK. И причина как не странно тот же реальный мир то, что сегодня считалось 'уникальным' совсем не факт что завтра станет 'не уникальным' и что же всю БД (да и приложения до кучи) после этого переделывать? А ограничения не только с помощью индексов можно реализовывать.

anc ★★★★★ ()
Ответ на: комментарий от anc

1. Я, скорее, теоретизировал. У ТС-то понятно, что все не очень гладко.

2. Я сторонник суррогатных PK в любом случае. Ты абсолютно верно подметил, что то, что казалось уникальным вчера, завтра перестанет быть уникальным. Но. На мой взгляд всегда, если нет действительно веских причин для обратного, надо реализовывать ограничения целостности данных на стороне базы и именно с помощью индексов и foreign key. Нельзя полагаться только на приложение, это всегда заканчивается болью и разочарованием. Однако такой подход тоже не очень удобен в некоторых ситуациях: например для процедуры клинапа наверняка придется отключать констрейнты.

alex_the_v ★★★ ()
Ответ на: комментарий от alex_the_v

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

Полностью поддерживаю. Сам сторонник такого подхода и всем советую по максимуму обеспечивать на стороне БД, многих бед позволяет избежать в дальнейшем . Только это можно реализовать и триггерами в том числе, более того определенные ограничения (сложнее чем например просто уникальность или fk) на стороне БД можно только ими обеспечить.

anc ★★★★★ ()
Ответ на: комментарий от anc

Только это можно реализовать и триггерами

Можно и триггерами, но триггеры, имхо, - последнее средство, для большинства вещей должно хватать check constraint. Вообще, триггеры - моветон и имеют кучу архитектурных недостатков, и если для реализации ограничения необходимы триггеры, то следует задуматься о природе этого ограничения, откуда оно возникает и так ли оно необходимо.

Еще Том Кайт говорил:

If I could remove three things from the database - they would be:


    Triggers
    Autonomous Transactions
    When Others (at least if not followed by RAISE or make when others ALWAYS re-raise as part of the language itself!!)

alex_the_v ★★★ ()
Ответ на: комментарий от anc

Вообще, дискуссия уже перешла в область личных предпочтений в архитектуре, сейчас мы тут такую демагогию разведем =)

alex_the_v ★★★ ()
Ответ на: комментарий от alex_the_v

Не полностью соглашусь по нескольким причинам.
1. В зависимости от реализаций СУБД, может оказаться, что только триггер позволит выполнить необходимое (помню условную выборку из других таблиц где-то нельзя было делать).
2. Иногда удобно просто для того, что бы вернуть «читаемую ошибку»
3. Действительно сложные ограничения, тут можно долго спорить плох такой подход или хорош, однако если он существует и позволяет выполнить больше - то почему бы этим не пользоваться
4. Бывают случаи когда то или иное ограничение надо снимать, а потом возвращать обратно, на уровне констрейнтов это сделать зачастую тяжелее.

anc ★★★★★ ()
Ответ на: комментарий от alex_the_v

Согласен, пора завязывать, от темы ТС далеко уходим :)

anc ★★★★★ ()

Дело в том, что мой вариант - первый. Второй представлен «профессионалами». Поэтому у меня возник вопрос: может я чего-то не знаю!? Хотелось-бы по этому поводу услышать профессиональных «базистов», - но пока не получилось ...

anonymus123 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.