База данных "указатели" на строки? - PullRequest
1 голос
/ 10 октября 2009

Есть ли способ иметь "указатели на строки" в базе данных?

например, у меня есть X строк продуктов, все эти строки представляют отдельные продукты, но многие имеют одинаковые значения полей, за исключением того, что их "id" и "color_id" различны.

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


Вопрос : Есть ли способ полностью заполнить несколько строк, а затем использовать специальное значение, чтобы «указать» на определенные значения поля?

Например:

id | field1   | field2   | field3   | color_id
-----------------------------------------------
1  | value1   | value2   | value3   | blue
2  | point[1] | point[1] | point[1] | red    (same as row 1, except id and color)
3  | point[1] | point[1] | point[1] | green  (same as row 1, except id and color)
4  | valueA   | valueB   | valueC   | orange
5  | point[4] | point[4] | point[4] | brown  (same as row 4, except id and color)
6  | valueX   | valueY   | valueZ   | pink
7  | point[6] | point[6] | point[6] | yellow (same as row 6, except id and color)

Я использую MySQL, но это более общий вопрос. Также, если это полностью идет вразрез с теорией баз данных, некоторые объяснения, почему это плохо, были бы оценены.

Ответы [ 9 ]

3 голосов
/ 10 октября 2009

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

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

Если у вас есть общие данные для каждого продукта, то создайте таблицу продуктов

create table product (
  product_id int,
  field1 ...,
  field2 ...,
  field3
)
with primary key on product_id

Основная таблица будет иметь поля id, color_id и product_id

если таблица продуктов выглядит как

product_id | field1   | field2   | field3  
-----------------------------------------------
1          | value1   | value2   | value3  
2          | valueA   | valueB   | valueC  
3          | valueX   | valueY   | valueZ   

Основной стол будет выглядеть как

id | product_id | color_id
--------------------------------
1  | 1          | blue
2  | 1          | red
3  | 1          | green  
4  | 2          | orange
5  | 2          | brown
6  | 3          | pink
7  | 3          | yellow
2 голосов
/ 12 октября 2009

Конечно, есть способ иметь указатели на строки в базе данных. Только не используйте реляционную СУБД. В 1960-х и 1970-х годах было несколько очень успешных продуктов СУБД, которые были полностью основаны на связывании записей путем вложения указателей на записи внутри других записей. Возможно, самым известным из них была IMS.

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

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

Как и предполагали другие, вам следует научиться нормализации. Когда вы это сделаете, вы узнаете, как разбивать таблицы на более мелкие таблицы с меньшим количеством полей (полей) в каждой таблице. Когда вам нужно использовать данные в объединенном виде, вы можете использовать реляционное соединение, чтобы собрать данные обратно. Реляционные объединения могут быть почти такими же быстрыми, как навигация по указателям, особенно если у вас построены правильные индексы.

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

1 голос
/ 10 октября 2009

Один из способов сделать это состоит в том, чтобы отделить столбцы, которые кажутся повторяющимися, и поместить их в отдельную таблицу. Дайте каждой строке в этой новой таблице уникальный идентификатор. Добавьте столбец к исходной таблице, который содержит идентификатор в новой таблице. Затем используйте отношение FOREIGN KEY между исходной таблицей и столбцом идентификатора новой таблицы.

0 голосов
/ 10 октября 2009

Вероятно, у вас должно быть две таблицы с отношением внешнего ключа.

Пример

Products:
  Id
  field1
  field2
  field3

ProductColors:
  Id
  ProductId
  Color
0 голосов
/ 10 октября 2009

Чтобы реализовать это в базе данных, нужно создать две таблицы:

object_id | field1 | field2 | field3

и

instance_id | object_id | colour

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

select t1.*, t2.colour from t1 join t2 on (t1.object_id=t2.object_id)
0 голосов
/ 10 октября 2009

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

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

id | field1   | field2   | field3   | color_id | object_id |
------------------------------------------------------------
1  | value1   | value2   | value3   | blue
2  | null     |  null    | null     | red      | 1         |
3  | null     |  null    | null     | green    | 1         |
4  | valueA   | valueB   | valueC   | orange
5  | null     |  null    | null     | brown    | 4         |
6  | valueX   | valueY   | valueZ   | pink
7  | null     |  null    | null     | yellow   | 6         |

Но помните: Это плохая идея. Не делай этого. Если бы ты хотел это сделать, это было бы как.

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

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

0 голосов
/ 10 октября 2009

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

0 голосов
/ 10 октября 2009

Создайте отдельные таблицы для значений field1, field2 и field three. Поместите туда существующие значения и ссылайтесь на них, указав их идентификаторы в текущей таблице.

0 голосов
/ 10 октября 2009

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

...