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

Так, на ответ Mehrdad на связанный вопрос я получаю его, что "надлежащий" столбец таблицы базы данных не хранит список. Скорее необходимо составить другую таблицу, которая эффективно содержит элементы упомянутого списка, и затем свяжитесь с ним непосредственно или через объединяющую таблицу. Однако тип списка, который я хочу создать, будет состоять из уникальных объектов (в отличие от фруктового примера связанного вопроса). Кроме того, объекты в моем списке явно отсортированы - что означает, что, если бы я сохранил элементы в другой таблице, я должен был бы отсортировать их каждый раз, когда я получил доступ к ним. Наконец, список является в основном атомарным в то любое время, я хочу получить доступ к списку, я захочу получить доступ ко всему списку, а не просто части его - таким образом, будет казаться глупым должным быть выпустить запрос базы данных для сбора частей списка.

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

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

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

Спасибо все!

John

ОБНОВЛЕНИЕ: Таким образом в первом шквале ответов я добираюсь, я вижу, что "можно пойти путем CSV/XML..., но СДЕЛАТЬ нет!". Таким образом, теперь я ищу объяснения почему. Укажите на меня на некоторые хорошие ссылки.

Кроме того, чтобы дать Вам лучшее представление о том, что я готов: В моей базе данных у меня есть таблица Function, которая будет иметь список (x, y) пары. (Таблица будет также иметь другую информацию, которая не имеет никакого значения для нашего обсуждения.) Я никогда не должен буду видеть часть списка (x, y) пары. Скорее я возьму всех их и выведу их на печать на экране. Я позволю пользователю перетаскивать узлы вокруг, чтобы иногда изменять значения или добавлять больше значений к графику.

99
задан Community 23 May 2017 в 11:54
поделиться

7 ответов

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

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

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

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

По сути, первое правило (или форма) нормализации гласит, что ваша таблица должна представлять отношение. Это означает, что:

  • Вы должны иметь возможность отличать одну строку от любой другой (другими словами, в вашей таблице должно быть что-то, что может служить первичным ключом. Это также означает, что ни одна строка не должна
  • Любой порядок данных должен определяться данными, а не физическим порядком строк (SQL основан на идее набора, что означает, что порядок только вы должны полагаться на то, что вы явно определяете в своем запросе)
  • Каждое пересечение строки / столбца должно содержать одно и только одно значение

Последняя точка, очевидно, является ключевой. хранить наборы для вас, а не для того, чтобы предоставить вам "ведро" для хранения набора самостоятельно. Да, это возможно. Нет, миру не конец. Однако вы уже искалечили себя в понимании SQL и передовой опыт, который сопровождает это, сразу переходя к использованию ORM. LINQ to SQL фантастичен, как и графические калькуляторы ar е. В том же ключе, однако, они не должны использоваться в качестве замены знания того, как на самом деле работают процессы, которые они используют.

Ваш список теперь может быть полностью «атомарным», и это не может измениться для этого проекта. Но вы, тем не менее, приобретете привычку делать аналогичные вещи в других проектах, и в конечном итоге (вероятно, быстро) столкнетесь со сценарием, в котором теперь вы вставляете свой быстрый и легкий список в столбце. подходить там, где это совершенно неуместно.Создание правильной таблицы для того, что вы пытаетесь сохранить, не требует особой дополнительной работы, и другие разработчики SQL не будут насмехаться над вами, когда они увидят ваш проект базы данных. Кроме того, LINQ to SQL обнаружит ваше отношение и автоматически предоставит вам соответствующий объектно-ориентированный интерфейс для вашего списка . Почему вы отказываетесь от удобства, предлагаемого вам ORM, чтобы вы могли выполнять нестандартные и необдуманные взломы базы данных?

162
ответ дан 24 November 2019 в 05:03
поделиться

В дополнение к тому, что сказали все остальные, я предлагаю вам проанализировать свой подход в более долгосрочной перспективе, чем сейчас. Это в настоящее время случай, когда предметы уникальны. Это в настоящее время случай, когда для пересортировки элементов потребуется новый список. Почти требуется, чтобы список был в настоящее время коротким. Несмотря на то, что у меня нет специфики предметной области, нетрудно предположить, что эти требования могут измениться. Если вы сериализуете свой список, вы теряете гибкость, которая не требуется в более нормализованном дизайне.Кстати, это не обязательно означает полноценные отношения «Многие: многие». У вас может быть только одна дочерняя таблица с внешним ключом для родительского элемента и символьный столбец для элемента.

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

3
ответ дан 24 November 2019 в 05:03
поделиться

Если вам нужно запросить список, сохраните его в таблице.

Если вам всегда нужен список, вы можете сохранить его как список с разделителями в столбце. Даже в этом случае, если у вас нет ОЧЕНЬ конкретных причин не делать этого, сохраните его в таблице поиска.

2
ответ дан 24 November 2019 в 05:03
поделиться

Вы можете просто забыть SQL совсем и пойти с "NoSQL" подходом. RavenDB, MongoDB и CouchDB приходят на ум как возможные решения. При подходе NoSQL вы не используете реляционную модель... вы даже не ограничены схемами.

14
ответ дан 24 November 2019 в 05:03
поделиться

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

Вот хороший ответ о том, как извлекать CSV с помощью LINQ.

1
ответ дан 24 November 2019 в 05:03
поделиться

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

0
ответ дан 24 November 2019 в 05:03
поделиться

Только один вариант не упоминается в ответах. Вы можете де-нормализовать дизайн вашей БД. Итак, вам нужны две таблицы. Одна таблица содержит правильный список, по одному элементу в строке, другая таблица содержит весь список в одном столбце (например, разделенный комой).

Здесь - "традиционный" дизайн БД:

List(ListID, ListName) 
Item(ItemID,ItemName) 
List_Item(ListID, ItemID, SortOrder)

Здесь - де-нормализованная таблица:

Lists(ListID, ListContent)

Идея в следующем - вы поддерживаете таблицу Lists с помощью триггеров или кода приложения. Каждый раз, когда вы изменяете содержимое List_Item, соответствующие строки в Lists обновляются автоматически. Если вы в основном читаете списки, это может работать вполне нормально. Плюсы - вы можете читать списки в одном операторе. Минусы - обновление занимает больше времени и усилий.

1
ответ дан 24 November 2019 в 05:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: