Структура таблицы журнала базы данных - PullRequest
4 голосов
/ 19 июля 2011

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

Я мог бы нормализовать и иметь:

  • LogEntry
  • LogEntryCategory
  • LogCategory
  • LogEntryProperty

LogEntry имеет много-много связей с LogCategory, а LogEntry имеет 1 ко многим с LogEntryProperty (которыйявляются парами имя / значение).

Альтернативой является денормализованная версия, которая имеет только LogEntry с категориями, хранящимися в виде списка разделенных запятыми списков строковых категорий и свойств, сохраняемых в виде ограниченного запятыми списка свойств в формате Name: Value.Как бы ужасно это не звучало с точки зрения отчетности, производительности и возможности поиска, я не уверен, что это не лучше.

Какая идея лучше?

Спасибо.

Ответы [ 2 ]

6 голосов
/ 20 июля 2011

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

enter image description here

Дело в том, чтобы не вставлять значение в таблицу свойств, если оно отсутствует, вдругими словами, все значения свойств НЕ НУЛЬЫ.

Чтобы упростить жизнь, определите представление

create view dbo.vLogs AS
select
      LogCategoryName
    , LogTime
    , p1_Value
    , p2_Value
    , p3_Value
    , p4_Value
    , p5_Value  
from LogEntry              as e
left join Property_1       as p1 on p1.LogEntryId   = e.LogEntryId
left join Property_2       as p2 on p2.LogEntryId   = e.LogEntryId
left join Property_3       as p3 on p3.LogEntryId   = e.LogEntryId
left join Property_4       as p4 on p4.LogEntryId   = e.LogEntryId
left join Property_5       as p5 on p5.LogEntryId   = e.LogEntryId
left join LogEntryCategory as x  on x.LogEntryId    = e.LogEntryId
left join LogCategory      as c  on c.LogCategoryID = x.LogCategoryID

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

select
      LogCategoryName
    , LogTime
    , p1_Value
    , p2_Value
from dbo.vLogs
where LogCategoryName = 'some_category' 
  and LogTime between from_time and to_time

и если вам нужно что-то простое, как это

select max(p1_Value)
from dbo.vLogs
where LogTime between '2011-07-18' and '2011-07-19'

Вот план выполнения, как вы можете видеть, участвуют только две таблицы.

enter image description here

Это называется устранением таблиц (объединений), и вам нужно, чтобы SQL Server, Oracle, PostgreSql 9.x, ... чтобы это работало - не будет работать на MySql (пока).

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

1 голос
/ 19 июля 2011

я бы посоветовал правильно нормализовать.

...