У меня странная проблема, которую я просто не могу понять.Rails 4 альтернативный первичный ключ с MySQL
Я хочу использовать способность кластеризации mysql для хранения связанных записей друг с другом на диске. Mysql с помощью первичного ключа в таблице, который для модели рельсов по умолчанию является идентификатором.
Однако для большого количества таблиц может иметь смысл первичный ключ таблицы быть, например, user_id, subscription_id, кластеризовать связанные записи рядом с каждым и делать очень эффективный поиск при запросе базу данных для всех абонентских подписей.
Чтобы сделать это, я создал таблицу MySQL, как:
execute('create table subscriptions (
id integer not null auto_increment,
user_id integer not null,
feed_id integer not null,
folder_id integer,
created_at datetime,
updated_at datetime,
primary key (user_id, feed_id),
key id (id)
) engine=InnoDB default charset=utf8');
Обратите внимание, что мой ПК является user_id, FEED_ID, но я до сих пор ID колонки настоящее, и я хочу, рельсы еще использовать это как то, что он считает ПК за столом.
Во-первых, это не будет работать вообще, пока я не установлен:
class Subscription < ActiveRecord::Base
self.primary_key = 'id'
...
end
Теперь приходит странная часть.
Когда я запускаю свои тесты, я получаю странную ошибку:
Mysql::Error: Field 'id' doesn't have a default value: INSERT INTO `subscriptions`
Однако - если я придерживаюсь приложение в режиме разработки и делать операции через веб-страницу, она работает просто отлично.
После много прибегая к помощи, я нашел обезьяну патч, чтобы остановить Rails настройки MySQL в более строгий режим:
class ActiveRecord::ConnectionAdapters::MysqlAdapter
private
alias_method :configure_connection_without_strict_mode, :configure_connection
def configure_connection
configure_connection_without_strict_mode
strict_mode = "SQL_MODE=''"
execute("SET #{strict_mode}", :skip_logging)
end
end
Если добавить это, мой тестовый костюм появляется на работу (для большинства тестов, но не все), но любые модели, которые создаются, имеют ИД нуля.
Снова в режиме производства через веб-страницу все работает отлично, а модели получают идентификатор auto_increment, как ожидалось.
У кого-нибудь есть идеи о том, что я могу сделать, чтобы мой тестовый набор работал правильно в этой настройке?
Не использовал бы первичный ключ UUID более надежный, чем этот? – tadman
Не уверен в UUID PK. Это действительно просто еще один суррогатный ПК, похожий на идентификационную последовательность. Я действительно не хочу начинать обсуждение кластеризации MySQL, но, имея PK в user_id, feed_id, это означает, что даже когда пользователи создают каналы в течение длительного периода времени, все они будут храниться рядом друг с другом на диске, позволяя всем читать по одной БД или двум, а не многим. Его также является естественным ключом на столе, так как таблица должна быть уникальной для этой пары. –
Почему бы не добавить уникальное ограничение/индекс на пару '(user_id, feed_id)' и оставить только ПК? Это, вероятно, будет проще с Rails, чем пытаться объединиться с ПК. –