Как структурировать (нормализовать?) Базу данных физических параметров? - PullRequest
1 голос
/ 28 апреля 2010

У меня есть набор физических параметров, связанных с различными предметами. Например:

Item, p1, p2, p3
a,     1,  2,  3
b,     4,  5,  6
[...]

, где px обозначает параметр x.

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

CREATE TABLE t1 (item TEXT PRIMARY KEY, p1 FLOAT, p2 FLOAT, p3 FLOAT);

Я мог бы получить параметр p1 для всех элементов с оператором:

SELECT p1 FROM t1;

Второй альтернативой является схема типа:

CREATE TABLE t1 (id INT PRIMARY KEY, item TEXT, par TEXT, val FLOAT)

Это кажется намного проще, если у вас много параметров (как у меня). Однако поиск параметров выглядит очень неловко:

SELECT val FROM t1 WHERE par == 'p1'

Что вы посоветуете? Стоит ли переходить на «сводную» (первую) версию или id, par, val (вторую) версию?

Большое спасибо.

EDIT

Для справки, я нашел следующий шаблон персистентности на сайте Примеры SQLAlchemy (вертикальное отображение):

"""Mapping a vertical table as a dictionary.

This example illustrates accessing and modifying a "vertical" (or
"properties", or pivoted) table via a dict-like interface.  These are tables
that store free-form object properties as rows instead of columns.  For
example, instead of::

  # A regular ("horizontal") table has columns for 'species' and 'size'
  Table('animal', metadata,
        Column('id', Integer, primary_key=True),
        Column('species', Unicode),
        Column('size', Unicode))

A vertical table models this as two tables: one table for the base or parent
entity, and another related table holding key/value pairs::

  Table('animal', metadata,
        Column('id', Integer, primary_key=True))

  # The properties table will have one row for a 'species' value, and
  # another row for the 'size' value.
  Table('properties', metadata
        Column('animal_id', Integer, ForeignKey('animal.id'),
               primary_key=True),
        Column('key', UnicodeText),
        Column('value', UnicodeText))

Because the key/value pairs in a vertical scheme are not fixed in advance,
accessing them like a Python dict can be very convenient.  The example below
can be used with many common vertical schemas as-is or with minor adaptations.

"""

Ответы [ 4 ]

1 голос
/ 28 апреля 2010

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

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

CREATE TABLE t1 ( item TEXT, par TEXT, val FLOAT, PRIMARY KEY (item, par))

Одним из ограничений второго подхода является то, что тип данных value должен быть одинаковым для всех параметров - ОК, если все значения с плавающей запятой, но для общности, это может быть строка с сопутствующей потерей проверки и необходимостью программного преобразования данных. 1006 *

Это повлияет на скорость запроса, но вы можете получить все параметры для термина с помощью запроса типа

SELECT par,value FROM t1 WHERE item='qitem'

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

1 голос
/ 28 апреля 2010

Нормализованным маршрутом будет размещение значений pX в ссылочной таблице по идентификатору.

ID     Item
1      a 
2      b 
3      c 


ID     Item    P
1      1       1
2      1       2
3      1       3
1 голос
/ 28 апреля 2010

Если вы предполагаете, что значение px будет превышать три значения (p1, p2 и p3) на p4 и т. Д., То первый подход потерпит неудачу, и продолжение добавления столбцов для p4, p5 и т. Д. Кажется ошибочным подход.

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

Item
  |
-----
| | |
ItemParameter

| | |
-----
  |
Parameter

Чтобы элемент мог иметь много параметров, а параметр мог существовать для многих элементов.

Таким образом, элемент a может иметь параметры p1, p2 и p3

(Item)
a
(ItemParameter)
a p1
a p2
a p2
(Parameter)
p1
p2
p3

Или пункт b может иметь параметры p1, p2, p6, p10 и p19

(Item)
b
(ItemParameter)
b p1
b p2
b p6
b p10
b p19
(Parameter)
p1
p2
p6
p10
p19

и т. Д.

1 голос
/ 28 апреля 2010

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

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

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

...