Рельсы ActiveRecord и нормализация БД - PullRequest
2 голосов
/ 01 декабря 2011

Каковы плюсы и минусы выделения дополнительных атрибутов 1: 1 в их собственную отдельную модель.

Например, я только что столкнулся с кодом Rails следующим образом:

class Dogs << ActiveRecord::Base
  # :id (pk), :breed, :weight, :height, :tail_length
end

class DogSpotsInfo << ActiveRecord::Base
  # :dog_id (pk), :spot_color, :avg_spot_size, :num_spots
end

Новот как я бы это сделал (оставив необязательные поля spot пустыми):

class Dogs << ActiveRecord::Base
  # :id, :breed, :weight, :height, :tail_length, :spot_color, :avg_spot_size, :num_spots
end

На уровне базы данных, я считаю, единственное отличие состоит в том, что запросы с дополнительными атрибутами потребуют еще одного соединения?

Есть ли еще какие-то минусы в первом подходе?Есть ли плюсы?

РЕДАКТИРОВАТЬ:

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

Еще один профессионал, о котором я могу подумать, это то, что он делает модели меньше и аккуратнее.Но если это и есть цель, возможно, вы могли бы сделать это, не затрагивая структуру БД, имея что-то вроде has_spots :spot?Какова лучшая практика здесь?

Ответы [ 4 ]

2 голосов
/ 27 сентября 2012
Отношения

1: 1 часто разлагаются, когда отношение имеет тип "Is-A", а не тип "Has-A". В расширенной модели ER это называется «специализация». В мире таблиц SQL это иногда называется «наследование таблиц классов». Вы можете найти любой из этих терминов для довольно хорошего рассмотрения соответствующего предмета.

Наследование таблиц классов отличается от «Наследования отдельных таблиц», в результате чего в тех местах, где значение не имеет значения, в одной таблице указывается NULLS. Это выглядит как ваш выбор для собак и пятен.

В мире "Автомобили" специализация может быть таблицей для "Транспортных средств", одной для "Авто" и одной для "Грузовиков". («Грузовики» называются «Грузовики» на моей стороне пруда.) Автомобили и Грузовики - это специализированные типы транспортных средств. Атрибуты, которые хранятся в грузовиках, а не в транспортных средствах, являются атрибутами, которые не имеют отношения к транспортным средствам, которые не являются грузовыми автомобилями.

Целью, как правило, является не повышение производительности, а улучшение формы запросов. Запросы, касающиеся только данных о грузовиках, могут запрашивать таблицу грузовиков. Запросы, касающиеся только данных об автомобиле, могут запрашивать таблицу транспортных средств. А запросы, которые включают данные о транспортных средствах и грузовиках, могут запрашивать представление, объединяющее транспортные средства и грузовики по общему столбцу.

Вопреки мнению других, узкие таблицы превосходят широкие, хотя эффект незначителен по сравнению с индексированием и объединениями.

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

Если бы я занимался вашим делом, я бы искал способы использовать специализацию для различных типов топлива, которые вы упомянули. Некоторые из ваших запросов могут в конечном итоге сканировать только одну из пяти специализированных таблиц (также называемых «таблицами подклассов»), таким образом, выполняется в пять раз быстрее.

2 голосов
/ 26 сентября 2012

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

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

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

Вы можете потенциально уменьшить общий размер базы данных, не сохраняя эту информацию в таблице, но для большинства небольших приложений (до 1 ТБ) вам следует оптимизировать производительность.

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

Вы можете получить такое же чувство ограничения, используя таблицу поиска всех возможных значений и позволяя пользователю выбирать только значения из таблицы поиска. Затем вернитесь и вставьте необработанные значения в таблицу собак. Это действительно имеет побочный эффект потенциального загрязнения таблицы «Собака» данными, которые не были должным образом очищены веб-приложением, но это было бы быстрой попыткой изолировать, какие данные не находятся внутри ограничений, по сравнению с таблицей поиска мест и исправлением проблема в веб-приложении.

0 голосов
/ 03 октября 2012

Плюсы денормализации:

  • Каждая таблица занимает память, чем меньше таблиц, тем меньше накладных расходов (однажды я имел дело с базой данных с 30K-таблицами с общим объемом данных 100 мегабайт, и использование памяти базы данных было огромным)

  • Ручной анализ можно легко выполнить, т. Е. Экспортировать 1 таблицу в Excel, таблицы Google и т. Д., И вы используете фильтры

Против

  • Много столбцов с нулевыми значениями.

Другой подход к балансированию большого количества столбцов и таблиц дополнительных атрибутов состоит в том, чтобы использовать сериализованные массивы для менее распространенных элементов, таких как iPod, а затем использовать сервер поиска (asticsearch, websolr и т. Д.), Который может обрабатывать запросы. с полным текстом ... Это позволит вам добавлять новые элементы в таблицу Cars без новых столбцов. Как автомобиль с самостоятельным вождением, автомобиль с самостоятельной парковкой.

0 голосов
/ 01 октября 2012

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

Это всегда плюс разделять вещи в отдельной таблице, в которой мы не уверены, придет значение или нет. как в вашем случае собака и собака, если только у 20% собак есть пятна, то нет необходимости хранить их в той же таблице базы данных, так как 80% столбцов будут равны нулю, и при извлечении данных из основной таблицы будет много данных будет выбран, что, безусловно, будет препятствовать производительности сервера. Если база данных небольшая, то, возможно, нет необходимости создавать вторую таблицу

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

так главное

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

2) Если база данных мала, вы можете перейти на последнюю

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...