Модель базы данных для полуструктурированных данных - PullRequest
0 голосов
/ 07 января 2010

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

     2005 2006  2007  2008  2009  2010  2011 2012
data1   2.5   3.5  
data2    
data3   

Второе приложение может получать данные либо из ole-ссылки из запроса Excel, либо из запроса odbc. Я хотел бы поместить данные в базу данных (sql-сервер или оракул), но я не уверен, как структурировать таблицы, уравновешивая то, как данные попадают в базу данных, взаимодействуют с пользователем и затем выводят запросы во второе приложение. Сфера деятельности, элементы и годы не фиксированы.

Я знаю, что это в основном сводная таблица, поэтому ответ, на который я смотрю, это таблица с {строка, элемент, год, значение}. Учитывая проблемы, связанные с получением и отправкой данных в этом формате, лучше ли мне использовать таблицу {line, element, year1..yearx} с произвольным числом столбцов для будущих лет? Это не классический случай значения атрибута сущности, но несколько похожий. Элементы меняются не очень часто, но их больше 300+. Я мог бы сгруппировать их в отдельные таблицы и использовать такую ​​структуру, как {line, year, element1..elementX} Это, вероятно, было бы проще всего разработать, но не кажется «правильным».

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

Ответы [ 3 ]

2 голосов
/ 07 января 2010

Это не EAV, это другой антипаттерн, который я называю Метаданные Tribbles . То есть они кажутся дружелюбными и удобными, но они, как правило, выходят из-под контроля.

Определите вторую таблицу с одним столбцом года, а числовое значение данных - с одним дополнительным столбцом.

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

1 голос
/ 07 января 2010

Может быть, что-то вроде этого:

lineofbusiness = (id, name)
elements = (lineofbusinessid, year, value)

Таким образом, таблица элементов может выглядеть так:

     lineofbusinessid  year  value
       1               2009   2.3
       1               2010   4.0
       1               2011   1.0
       2               2009   9.0
  

и т.д.

0 голосов
/ 08 января 2010

Поскольку вы планируете использовать систему управления реляционными базами данных, я бы сохранил эти данные в виде набора нормализованных таблиц. Первый удар (все это основано на SQL Server 2005, и извините,):

CREATE TABLE MyData
 (
   LineOfBusiness  varchar(50)  not null
  ,Year            smallint     not null
  ,Element         varchar(50)  not null
  ,Value           float        not null
  ,constraint PK_MyData
    primary key (LineOfBusiness, Year, Element)
 )

Наличие двух varchar (50) в первичном ключе может считаться неэффективным, особенно если вы в конечном итоге с большим количеством данных. (а) я бы не потел, пока вы не наберете 64к, но (б) к тому времени, когда вы нажмете мегабайты данных, будет слишком поздно возвращаться и пересматривать ваши архитектура - так может быть и с первого раза.

Может быть эффективно переместить LineOfBusiness в таблицу поиска:

CREATE TABLE LineOfBusiness
 (
   LineOfBusinessId  int          not null
    constraint PK_LineOfBusiness
     primary key
  ,Description       varchar(50)  not null
 )

Если «элементы» можно повторять между направлениями бизнеса, это определенно более эффективно чтобы переместить его в таблицу поиска:

CREATE TABLE Element
 (
   ElementId    int          not null
    constraint PK_Element
     primary key
  ,Description  varchar(50)  not null
 )

Год - это простое числовое значение, которое падает между 1900 и 2100 (а если нет, то да?), поэтому нет необходимости нормализовать это. Полезна ли справочная таблица для года, зависит от требований приложения. (Может быть, имеет смысл иметь столбцы FirstYear и LastYear в LineOfBusiness?)

Исходя из приведенных выше двух таблиц и работая в реляционной целостности, вы получите

CREATE TABLE MyData
 (
   LineOfBusinessId  int       not null
    constraint FK_MyData__LineOfBusiness
      foreign key references LineOfBusiness (LineOfBusinessId)
  ,Year              smallint  not null
  ,ElementId         int       not null
    constraint FK_MyData__Element
      foreign key references Element (ElementId)
  ,Value             float     not null
  ,constraint PK_MyData
    primary key (LineOfBusinessId, Year, ElementId)
 )

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

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