Как сохранить массив или несколько значений в одном столбце - PullRequest
28 голосов
/ 15 июня 2011

Запуск Postgres 7.4 (Да, мы находимся в процессе обновления)

Мне нужно хранить от 1 до 100 выбранных элементов в одном поле в базе данных. В 98% случаев будет введен только 1 элемент, а в 2% случаев (если таковой будет) будет несколько элементов.

Предметы - не более чем текстовое описание (на данный момент) длиной не более 30 символов. Это статические значения, которые выбирает пользователь.

Требуется знать оптимальный тип данных столбца, используемый для хранения нужных данных. Я думал BLOB, но не знал, является ли это излишним. Может быть, JSON?

Также я думал об ENUM, но сейчас я не могу этого сделать, так как мы работаем с Postgres 7.4

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

Ответы [ 2 ]

40 голосов
/ 15 июня 2011

У вас есть пара вопросов здесь, поэтому я отвечу на них отдельно:

Мне нужно сохранить количество выбранных элементов в одном поле в базе данных

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

Вы упомянули, что думали об использовании ENUM. Эти значения фиксированы? Ты знаешь их раньше времени? Если это так, то это будет моя структура:

Базовая таблица (какая у вас сейчас):

| id primary_key sequence
| -- other columns here.

Таблица предметов:

| id primary_key sequence
| descript VARCHAR(30) UNIQUE

Таблица карт:

| base_id  bigint
| items_id bigint

Таблица сопоставления будет иметь внешние ключи, поэтому base_id сопоставляется с базовой таблицей, а items_id сопоставляется с таблицей элементов.

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

Какой формат я должен использовать для хранения данных?

Если вам нужно сделать что-то подобное, почему бы просто не использовать строку, обозначенную символом? Это займет меньше вычислительной мощности, чем CSV, XML или JSON, и будет короче.

Какой тип столбца мне следует использовать для хранения данных?

Лично я бы использовал TEXT. Похоже, вы не сильно выиграете, если сделаете это BLOB, и, по моему опыту, TEXT будет легче читать, если вы используете какую-то форму IDE.

6 голосов
/ 16 июня 2011

Ну, есть тип массива в последних версиях Postgres (не 100% в PG 7.4). Вы даже можете индексировать их, используя индекс GIN или GIST. Синтаксисы:

create table foo (
  bar  int[] default '{}'
);

select * from foo where bar && array[1] -- equivalent to bar && '{1}'::int[]

create index on foo using gin (bar); -- allows to use an index in the above query

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

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