2010-01-18 3 views
16

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

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

Допустим, они проводятся в таблице под названием exams с колоннами temperature, pressure и т.д. ... (а также id, patient_id и timestamp). Большинство измерений хранятся как поплавки, но некоторые из них относятся к другим типам (строки, целые числа ...)

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

Он не уверен, как сохранить эти настраиваемые поля.

Он склоняется к отдельной таблице (скажем, таблица custom_exam_data с полями, как exam_id, custom_field_id, float_value, string_value, ...)

Я волнуюсь, что это сделает поиск и более трудно достичь и менее эффективной ,

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

Он беспокоится об изменении базы данных динамически и с разными схемами для каждой медицинской единицы.

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

Примечание:

  • он использует Ruby On Rails, но я думаю, этот вопрос довольно много рамок агностика, за исключением того факта, что он ищет только для решений в области только для баз данных SQL.

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

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

  • (добавлено) Входы пользователя будут отфильтрованы как для стандартных полей, так и для настраиваемых полей. Например, числа будут проверяться в пределах заданного диапазона (не может иметь температуру от -12 или +444) и т. Д. Таким образом, преобразование в соответствующий тип SQL не является проблемой.

ответ

8

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

Создание строк столбцов UserAttribute или Key/Value звучит привлекательно, но это приводит к inner-platform effect, где вам нужно повторно реализовать внешние ключи, типы данных, ограничения, транзакции, проверку, сортировку, группировку, вычисления, и другие. внутри вашей РСУБД. Вы можете просто использовать плоские файлы, а не SQL вообще.

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

+0

Спасибо за указание на этот термин (внутриплатформенный эффект). Это ново для меня, но я чувствую, что здесь очень хорошо. –

1

Я видел использование идеи вашего друга в коммерческом бухгалтерском пакете. Таблица была разделена на два, сначала содержащихся поля, только определенные системой, во вторых - поля, такие как USER_STRING1, USER_STRING2, USER_FLOAT1 и т. Д.Таблицы были связаны идентификационным значением (когда запись вставлена ​​в основную таблицу, запись с тем же идентификатором вставлена ​​во вторую). Каждая таблица, в которой нужны поля пользователя, была разделена так.

3

Microsoft Dynamics CRM достигает этого путем изменения дизайна базы данных при каждом изменении. Надеюсь, я думаю.

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

1

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

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

+0

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

+0

@ Chuck Vose, лучший способ хранить вещи как струны. –

+0

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

1

Я был бы склонен хранить измерения в базе данных в виде строки (varchar) с другим столбцом, определяющим тип измерения. Мое рассуждение состоит в том, что он, предположительно, исходит из пользовательского интерфейса в виде строки, и приведение к любому другому типу данных может привести к повреждению до того, как пользовательский вход get будет сохранен.

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

+0

Хорошее предложение, но сортировка или другие вычисления не будут работать хорошо. Легко (и обязательно!) Фильтровать входные данные пользователя в любом случае, чтобы убедиться, что они находятся в допустимом диапазоне (в случае номеров). Эта фильтрация уже написана для стандартных полей. Я добавил это к своему вопросу. –

1

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

Общая идея заключается в том, что есть таблица схем со списком полей. В каждой строке действительно только два столбца: столбец «String» и столбец «column»: String. Для каждого из этих столбцов он фактически определяет целую таблицу, содержащую только идентификатор и фактические данные для этого столбца.

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

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

Что касается поиска, то я хотел бы проиндексировать содержимое страницы, а не содержимое базы данных. Используйте Solr для синтаксического анализа полученных страниц и хранения ссылок на фактическую страницу вместо поиска в базе данных с использованием умного SQL.

+0

Если я правильно понимаю, у Drupal есть гибрид обеих стратегий? Он динамически изменяет схему БД (добавлением таблиц) и должен выполнять объединения (поскольку данные разделены в разных таблицах) ... Я не вижу вверх, это похоже на худшее из обоих подходов, но, возможно, m что-то не хватает? –

+0

Ха, ты, наверное, нет. Есть несколько действительно хороших улучшений производительности только для одного столбца на таблицу. В любом случае, это _is_ совершенно причудливая структура, и я бы не стал торговать ею за мой магазин ключей redis. –

+0

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

0

Я бы сохранил эти настраиваемые поля в таблице, где каждая запись (dataType, dataValue, dataUnit) использовалась бы в одной строке. Таким образом, было бы отношение oneToMany от одного образца к данным. Вы также можете создать таблицу для записи всех типов видов вырезок, которые вы использовали бы. Например:

create table DataType 
(
id int primary key, 
name varchar(100) not null unique 
description text, 
uri varchar(255) //<-- can be used for an ONTOLOGY 
) 


create table DataRecord 
(
id int primary key, 
sample_id int not null,//<-- reference to the sample 
dataType_id int not null, //<-- references DataType 
value varchar(100),//<-- the value as string 
unit varchar(50)//<-- g, mg/ml, etc... but it could also be a link to a table describing the units just like DataType 
) 
1

Определите две новые таблицы: custom_exam_schema и custom_exam_data.

custom_exam_data имеет столбец exam_id, а также дополнительный столбец для каждого настраиваемого атрибута.

custom_exam_schema бы ряд, чтобы описать, как интерпретировать каждую из колонок из custom_exam_data таблицы. Это будет иметь столбцы как name, type, minValue, maxValue и т.д.

Так, например, чтобы создать настраиваемое поле, чтобы отслеживать количество пальцев у человека, вы бы добавить к ('fingerCount', 'number', 0, 10)custom_exam_schema, а затем добавить колонку названный fingerCount на стол exam.

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

+0

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

7

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

Entity-Attribute-Value (EAV) Model

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

+1

+1 для XML: гибкий до n-й степени, а производительность может быть улучшена на SQL Server с использованием столбцов Typed-XML (хотя ввод столбца может ограничивать гибкость, но если используется гибкая схема XSD, существует потенциал для справедливый баланс) – STW

+0

Спасибо за ссылку на EAV. Это не применимо здесь; если медицинская группа решит, что для их целей важно добавить уровень сахара в кровоток, скажем, тогда они добавят, что с использованием пользовательских полей, и это будет введено для подавляющего большинства клиентов. Если я должен был сериализовать что-либо, я бы использовал YAML, но сериализация здесь ужасная идея (см. Последние 2 примечания). –

+0

YAML не поддерживается какой-либо базой данных, которую я знаю (и не имеет спецификации схемы), в то время как XML может быть строго типизированным и проиндексированным в нескольких из них. Я также предложил возможность вложенных наборов, которые были бы более результативными. Я не думаю, что тот факт, что у вас есть противоречивые требования, требует ниспроверки. – Aaronaught

0

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

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

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

Учитывая, что база данных:
- должна быть гибкой
- которые могут быть добавлены данные из нескольких таблиц и настроить
- что вы могли бы хотеть, чтобы сохранить целостность основной структуры базы данных для распространения и цель единообразия
- эти данные ДОЛЖНЫ иметь предел, а также предупреждения и предупреждения
- эти данные должны иметь единицы измерения (10 кг или 10 фунтов)?
- что данные могут иметь широкий выбор вариантов
- что данные могут быть с различными правами (от простого пользователя до администратора)
- что эти данные могут быть необходимы для создания отчетов без изменения коды (автоматизация)
- что эти данные могут потребоваться для проведения перекрестного справочного анализа в системе без изменения кода пользовательского стола будет моим решением, изменение каждой таблицы будет слишком рискованным.

+0

Я бы хотел узнайте, какой именно реальный риск существует. –