Во время нашей последней еженедельной встречи человек, не имеющий опыта работы в администрировании баз данных, поднял этот вопрос:
"Будет ли сценарий, который оправдывает хранение данных в виде строки (строки) вместо нескольких строк?"
Давайте предположим таблицу с именем, countryStates
где мы хотим хранить состояния страны; Я буду использовать США для этого примера и не буду перечислять все штаты ради лени.
Там у нас будет две колонки; один звонил, Country
а другой звонил States
. Как обсуждалось здесь , и предложенный @ srutzky в ответ , то PK
будет код определяется стандартом ISO 3166-1 альфа-3 .
Наша таблица будет выглядеть так:
+---------+-----------------------+-------------------------------------------------------+
| Country | States | StateName |
+---------+-----------------------+-------------------------------------------------------+
| USA | AL, CA, FL,OH, NY, WY | Alabama, California, Florida, Ohio, New York, Wyoming |
+---------+-----------------------+-------------------------------------------------------+
Задавая тот же вопрос другу-разработчику, он сказал, что с точки зрения объема трафика данных это может быть полезно, но не в том случае, если нам нужно манипулировать этими данными. В этом случае должна быть информация о коде приложения, которая могла бы преобразовать эту строку в список (скажем, что программное обеспечение, которое имеет доступ к этой таблице, должно создать поле со списком).
Мы пришли к выводу, что эта модель не очень полезна, но у меня возникло подозрение, что может быть способ сделать это полезным.
Я хотел бы спросить, видел ли кто-нибудь из вас, слышал или сделал что-то подобное таким образом, который действительно работает .
источник
a;b;c
, использовать передний конец для разбора вашей строки вы получите тоa
,b
,c
и нести на выполнение делать что - то с ними, может быть ?. Чувствую, что это может удовлетворить какую-то конкретную потребность таким образом ... Если подумать, нет. Вы всегда можете хранить идентификаторы, присоединяться к своим таблицам и создавать объединенную строку, которая может отправлять содержимое в FE ...Ответы:
Начнем с того, что заголовок текущего вопроса, относящийся к «хранению данных в виде строки вместо столбцов», немного сбивает с толку. Говоря о хранении данных в виде строк вместо чего-то другого, это обычно относится к сериализации всего в строковый формат вместо правильного / сильного типа данных (например,
INT
илиDATETIME
). Но если спросить о сохранении данных в виде нескольких значений в одном поле, а не в отдельных строках, это немного отличается. И чтобы быть справедливым, хотя объединение значений проще всего сделать со строками, это также можно сделать с помощьюINT
иBINARY
типов, либо с помощью маскировки битов, либо аналогичным образом резервируя определенные позиции, чтобы иметь разные значения. Поскольку второе толкование - это то, о чем фактически спрашивают, основываясь на тексте Вопроса, давайте обратимся к этому.Одним словом: Нет. Если вы храните фактические точки данных, то это принесет только боль (с точки зрения кода и производительности), поскольку это является ненужным осложнением. Если это значение, которое когда-либо будет храниться только как единое целое, обновляться как единое целое и никогда не разбираться в базе данных, тогда это может быть нормально, поскольку это примерно аналогично хранению изображения или PDF. В противном случае любая попытка проанализировать данные будет недействительной с использованием любых индексов (например, с использованием
LIKE '%something%'
, илиCHARINDEX
, илиPATINDEX
, илиSUBSTRING
, и т. Д.).Если вам нужно хранить отдельные значения в одном поле одной строки, то для этого есть более подходящие средства: XML или JSON. Это анализируемые форматы ( XML / JSON ), и XML можно даже индексировать . Но в идеале эти данные должны храниться в правильно заполненных полях, чтобы они могли быть действительно полезными.
И, пожалуйста, не забывайте, что целью СУБД является хранение данных таким образом, чтобы их можно было извлекать и манипулировать ими как можно более эффективно в рамках ограничений, налагаемых совместимостью с ACID . Получение сцепленных значений достаточно плохо из-за необходимости сначала анализировать значения, и это не индексируется. Но манипулирование часто означает замену всего большого двоичного объекта просто для обновления его части (при условии, что не существует шаблона для использования с
REPLACE
функцией). Тип данных XML, по крайней мере, позволяет использовать XML DML для упрощенных обновлений, хотя они все еще не так быстры, как простое обновление правильно смоделированных данных.Кроме того, учитывая сценарий, подобный тому, который показан в приведенном выше вопросе, объединяя все коды состояний вместе, вы не сможете использовать внешний ключ (в любом направлении) для этих значений.
А что, если бизнес-требования со временем меняются, и вам необходимо отслеживать дополнительные свойства этих элементов? С точки зрения «штатов», как насчет столиц, или населения, или порядка сортировки, или чего-то еще? Правильно хранятся в виде строк, вы можете добавить больше столбцов для дополнительных свойств. Конечно, у вас может быть несколько уровней данных, которые можно анализировать, например,
|StateCode,Capital,Population |StateCode,Capital,Populate|...
но, надеюсь, любой может увидеть, что проблема экспоненциально выходит из-под контроля. Конечно, эта конкретная проблема довольно легко решается с форматами XML и JSON, и это их значение, как указано выше. Но вам все равно понадобится очень веская причина для использования любого из них в качестве начального средства моделирования, поскольку ни один из них не будет столь же эффективным, как использование дискретных полей в отдельных строках.источник
Я действительно использовал что-то подобное для очень ограниченной цели. Мы создали таблицу заголовков для выходных файлов. Они были специально построены и были в основном только заголовками столбцов, но не совсем. Таким образом, данные выглядели примерно так
По сути это выглядело как список с разделителями. И в одном смысле это было. Но для наших целей это была единственная длинная строка.
Это хитрость здесь. Если вы никогда не планируете анализировать список, то его стоит сохранить. Однако, если вам понадобится или даже потребуется проанализировать список, то стоит потратить дополнительное место и время, чтобы разделить его и сохранить в отдельных строках.
источник
Я использовал это однажды с довольно маленькой таблицей, например:
А затем сохранить значения
CRM,SMS,SELF-CARE
вvalid_channel
.Вся таблица содержит около 10 записей.
valid_channel
содержит значения, которые на самом деле должны быть в таблице связей, которая отображает отношение «многие ко многим». Столt1
не будет интенсивно использоваться, поэтому мы просто решили пойти по этому пути. Тем не менее, некоторые политики были вовлечены в это решение (см. Ниже).Но в целом я этого избегаю, это не 3NF.
Место, где я сейчас работаю, имеет множество таких колонок повсюду. Их обоснование заключается в том, что это облегчает их запросы: вместо объединения трех таблиц с помощью таблицы ссылок они могут перейти непосредственно к таблице определения с помощью
LIKE
. НапримерУжасно + на Oracle это отключает использование индекса из-за запуска
'%,'
.источник
LIKE
или простое соединение?LIKE
будет медленнее, особенно если данные правильно смоделированы для использованияTINYINT
поля PK вchannel_def
. Тогда нужно только сравнить один байт между двумя таблицами. Здесь он должен анализировать строку, символ за символом (по крайней мере, до тех пор, пока условие не будет выполнено), и выполняет поиск без учета регистра (на основе заданной таблицы, не показывающей используемое_BIN2
сопоставление). Это также делает недействительными индексы на SQL Server. Я ответил на это в своем ответе, сказав, что при разборе нельзя использовать индексы. Я просто обновил свой ответ, чтобы сделать его более понятным.LIKE
предложению и не дает странных результатов, это может вызвать другие проблемы или по крайней мере, сделать отладку сложнее / дольше). Это также усложняет обновлениеvalid_channels
поля. Это не значит, что это не работает, просто нет веских причин для этого.Это было сделано здесь, на SE. Как пишет Марк Гравелл :
Этот «новый формат» был следующим шагом по сравнению со «старым форматом», который немного отличался и был выбран для использования функции полнотекстового поиска SQL Server, поэтому некоторые преимущества не имеют значения, если вы делаете это с нуля.
Предположительно, они не полностью нормализовали вещь по причинам объема работы и производительности.
источник
Ну, одно из основных преимуществ использования строк и других типов данных - отправка их из SQL Server в C #, C, C ++ (и т. Д.) С использованием SQLCLR, когда может потребоваться высокая производительность. Вы могли бы даже создать представление или хранимую процедуру для представления реляционных данных нереляционно - как вы сделали для примера выше для этой цели.
Смотрите этот пример:
http://aboutsqlserver.com/2013/07/22/clr-vs-t-sql-performance-considerations/
per Wikipedia: SQL CLR или SQLCLR (SQL Common Language Runtime) - это технология для размещения общеязыкового движка Microsoft .NET в SQL Server. SQLCLR позволяет размещать управляемый код и выполнять его в среде Microsoft SQL Server.
источник
На мой взгляд, ответ будет отрицательным. Я не использовал этот подход и избежал бы его - я не могу придумать причину, по которой я пошел бы по этому пути. Вы склоняетесь к миру JSON / NoSQL с массивом.
У нас были аналогичные варианты дизайна в предыдущей роли, когда команда архитекторов хотела иметь поле «Данные», которое было разделено, а затем преобразовано в двоичный файл. Мы не пошли по этому маршруту в конце концов по нескольким причинам.
Если бы вам пришлось присоединиться к данным такого типа, это был бы один уродливый опыт. Обновление отдельных элементов строки также будет неприятным.
источник