Пары ключ-значение в реляционной базе данных - PullRequest
67 голосов
/ 24 сентября 2008

Есть ли у кого-то опыт хранения пар ключ-значение в базе данных?

Я использовал этот тип таблицы:

CREATE TABLE key_value_pairs ( 
    itemid           varchar(32) NOT NULL,
    itemkey         varchar(32) NOT NULL,
    itemvalue       varchar(32) NOT NULL,
    CONSTRAINT ct_primarykey PRIMARY KEY(itemid,itemkey)
)

Тогда, например, могут существовать следующие строки:

 itemid            itemkey        itemvalue    
 ----------------  -------------  ------------ 
 123               Colour         Red            
 123               Size           Medium             
 123               Fabric         Cotton

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

CREATE TABLE key_value_pairs ( 
    itemid            varchar(32) NOT NULL,
    itemkey1        varchar(32) NOT NULL,
    itemvalue1      varchar(32) NOT NULL,
    itemkey2        varchar(32) NOT NULL,
    itemvalue2      varchar(32) NOT NULL,
 . . .etc . . .
)

Это будет проще и быстрее запрашивать, но не обладает расширяемостью первого подхода. Любой совет?

Ответы [ 18 ]

1 голос
/ 24 сентября 2008

Нарушение правил нормализации хорошо, если бизнес-требования все еще могут быть выполнены. key_1, value_1, key_2, value_2, ... key_n, value_n может быть в порядке, вплоть до того момента, когда вам нужно key_n+1, value_n+1.

Моим решением была таблица данных для общих атрибутов и XML для уникальных атрибутов. Это означает, что я использую оба. Если все (или большинство вещей) имеют размер, тогда размер - это столбец в таблице. Если только объект A имеет атрибут Z, то Z сохраняется в виде XML, аналогично уже полученному ответу Питера Маршалла.

1 голос
/ 24 сентября 2008

первый метод вполне нормально. Вы можете создать UDF, который извлекает нужные данные, и просто вызывать это.

0 голосов
/ 07 марта 2015

Времена изменились. Теперь у вас есть другие типы баз данных, которые вы можете использовать помимо реляционных баз данных. Выбор NOSQL теперь включает хранилища столбцов, хранилища документов, графики и мультимодели (см .: http://en.wikipedia.org/wiki/NoSQL).

Для баз данных Key-Value вы можете выбрать (но не ограничиваясь ими) CouchDb, Redis и MongoDB.

0 голосов
/ 24 сентября 2008

Вторая таблица плохо нормализована. Я бы придерживался первого подхода.

0 голосов
/ 24 сентября 2008

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

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

Я могу написать более подробную информацию о том, что мы делаем, если потребуется.

0 голосов
/ 28 ноября 2008

Ваш пример не очень хороший пример использования пар ключ-значение. Лучшим примером будет использование чего-то вроде таблицы комиссионных, таблицы Customer и таблицы Customer_Fee в приложении биллинга. Таблица оплаты будет состоять из таких полей, как: fee_id, fee_name, fee_description Таблица Customer_Fee будет состоять из таких полей, как: customer_id, fee_id, fee_value

0 голосов
/ 25 сентября 2008

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

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

0 голосов
/ 24 сентября 2008

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

Если ключи являются известным набором, и их не так много (<10, может быть <5), то я не вижу проблемы в том, чтобы они были в качестве столбцов значений на элементе. </p>

Если имеется среднее число известных фиксированных ключей (10–30), возможно, имеется другая таблица для хранения item_details.

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

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