Правильное использование таблиц поиска

dba.stackexchange https://dba.stackexchange.com/questions/9011

  •  16-10-2019
  •  | 
  •  

Вопрос

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

Допустим, у меня есть стол под названием сотрудники:

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

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

ID  Position
1   Manager
2   Sales

Но как далеко я могу продолжать разбить информацию на меньшие таблицы поиска, прежде чем она станет неуправляемой? Я мог бы создать гендерную таблицу и иметь 1, соответствующую мужчине, и 2 соответствуют женщине в отдельной таблице поиска. Я мог бы даже поместить lname и fnames в столы. Все записи «Джона» заменяются иностранным ключом 1, который указывает на таблицу Fname, в которой говорится, что идентификатор 1 соответствует Джону. Если вы зайдете в эту кроличье дыру слишком далеко, однако, столик ваших сотрудников превращается в беспорядок иностранных ключей:

ID  LName   FName   Gender  Position
1   1       1       1       1
2   1       2       2       2
3   2       1       1       2

Хотя это может или не может быть более эффективным для обработки сервера, это, безусловно, нечитаемо для нормального человека, который может пытаться его поддерживать, и затрудняет разработчик приложений, пытающегося получить к нему доступ. Итак, мой настоящий вопрос в том, как далеко слишком далеко? Существуют ли «лучшие практики» для такого рода вещи или хороший набор руководящих принципов? Я не могу найти никакой информации в Интернете, которая действительно прижимает хороший, полезный набор руководящих принципов для этой конкретной проблемы, который у меня есть. Дизайн базы данных для меня старая шляпа, но хороший дизайн базы данных очень новый, поэтому чрезмерно технические ответы могут быть над моей головой. Любая помощь будет оценена!

Это было полезно?

Решение

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

Вы смешиваете две разные проблемы. Одной из проблем является использование таблицы «поиска»; Другой - использование суррогатных клавиш (идентификационные номера).

Начните с этой таблицы.

ID  LName   FName   Gender  Position
1   Doe     John    Male    Manager
2   Doe     Jane    Female  Sales
3   Smith   John    Male    Sales

Вы можете создать таблицу «поиска» для таких позиций.

create table positions (
  pos_name varchar(10) primary key
);

insert into positions
select distinct position 
from employees;

alter table employees
add constraint emp_fk1
foreign key (position) 
  references positions (pos_name);

Ваша оригинальная таблица выглядит точно так же, как и перед созданием таблицы «поиск». И таблица сотрудников требует нет Дополнительные соединения, чтобы получить полезные, читаемые на человеку данные.

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

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

Другие советы

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

  • Пол самостоятельно описывает (скажем M или же F), ограниченным 2 значениями, и может быть обеспечено с ограничением проверки. Вы не добавите новые полов (игнорируя коллока политкорректности)
  • Первое имя «Джон» не является частью ограниченного, ограниченного набора данных: потенциальный набор данных массивен до такой степени безграничной, поэтому он не должен быть поиском

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

Кроме того, когда у вас будет миллион сотрудников, то более эффективно хранить TinyInt PosipId, чем Varchar.

Давайте добавим новую колонку «валюта зарплаты». Я использовал бы здесь таблицу поиска с ключом CHF, GBP, EUR, USD и т. Д. Я бы не использовал суррогатный ключ. Это может быть ограничено ограничением проверки, таким как пол, но это ограниченный, но расширяемый набор данных, таких как позиция. Я привожу этот пример из -за того, что я бы использовал естественный ключ, даже если он появляется в миллионе рядов данных сотрудника, несмотря на то, что он был Char (3), а не Tinyint

Итак, подвести итоги, вы используете таблицы поиска

  1. где у вас есть конечные, но расширяемые данные настройки в столбце
  2. где не описывается
  3. избегать Аномалии модификации данных

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

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

Чтобы повторно использовать любимую цитату

«Мудрый человек однажды сказал мне», - нормализуется, пока не повредит, денормализуйте, пока он не сработает ».

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

Возьмите этот сокращенный пример высоко нормализованных таблиц из реальной системы

CREATE TABLE PROPERTY
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_TYPE
(ID                          NUMBER(9)           NOT NULL);

CREATE TABLE PROPERTY_LOCALE 
PROPERTY_ID                  NUMBER(9)           NOT NULL,
(LOCALE_ID                   NUMBER(9)           NOT NULL,  --language 
VALUE                        VARCHAR2(200)       NOT NULL);

CREATE TABLE PROPERTY_DEPENDENCY
(PROPERTY_ID                 NUMBER(9)           NOT NULL,
 PARENT_PROPERTY_ID          NUMBER(9)                   ,
 PROPERTY_TYPE_ID            NUMBER(9)           NOT NULL);

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

  CREATE TABLE CASE_PROPERTY
  (ID                        NUMBER(9)           NOT NULL,
  PARENT_ID                  NUMBER(9),
  CASE_ID                    NUMBER(9)           NOT NULL,
  PROPERTY_ID                NUMBER(9),
  PROPERTY_TYPE_ID           NUMBER(9)           NOT NULL);

Это выглядит нормально: Получите все случаи с Property_ID в одном выборе

Давайте получим список, чтобы выбрать из

 Select pl.value, pd.property_id
 from property_locale pl, property_dependency pd
 where pl.property_id = pd.property_id
 and pd.property_type_id = 2;  --example number

Теперь попробуйте выбрать все свойства случая, если у него есть свойства 3 и 4 и 4 или нет ...

SELECT   cp2.case_id,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 2
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE1,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 34
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE2,
         (SELECT   pl.VALUE
            FROM   case_property cp, property_locale pl
           WHERE       cp.property_id = pl.property_id
                   AND CP.PROPERTY_TYPE_ID = 4
                   AND pl.locale_id = 2
                   AND cp.case_id = cp2.case_id)
            AS VALUE3
  FROM   case_property cp2
 WHERE   cp2.case_id = 10293  

Это просто больно ... даже когда вы используете более элегантные способы справиться с этим. Тем не менее, добавьте немного нормализации DE, разрывая свойства, которые в случае будет только одно Property_ID, и это может быть намного лучше.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top