Как получить "традиционный" результат из одной строки из таблицы, ориентированной на значение ключа - PullRequest
3 голосов
/ 07 апреля 2011

У меня есть таблица, которая была разработана в виде таблицы ключ-значение, например

ID | key | value
1  | abc | value 1
2  | def | value 2
3  | geh | value 3

, которая имеет различные преимущества в том, что мы делаем с данными.Единственный недостаток в том, что я не могу легко сортировать по такой таблице ключ-значение.Какой был бы интеллектуальный / обычный способ получить набор результатов со всеми ключами / значениями, «выровненными» традиционным способом, с ключами, появляющимися как поля:

abc     | def     | geh
value 1 | value 2 | value 3

Ответы [ 2 ]

1 голос
/ 07 апреля 2011

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

Чтобы максимально использовать его, вы можете создать индекс на вкладке key-kvalue с помощью:

CREATE UNIQUE INDEX myindex ON keyvaluetable(key)

Я предположил, что у вас есть UNIQUE значения в поле key. Если нет, вы можете, конечно, удалить эту часть.

0 голосов
/ 07 апреля 2011

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

root@localhost [kris]> create table overnormal ( id serial, k varchar(20) not null, v varchar(20) not null);
Query OK, 0 rows affected (0.96 sec)

root@localhost [kris]> insert into overnormal values ( 1, 'abc', 'value 1'), (2, 'def', 'value 2'), (3, 'geh', 'value 3');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

root@localhost [kris]> select * from overnormal;
+----+-----+---------+
| id | k   | v       |
+----+-----+---------+
|  1 | abc | value 1 |
|  2 | def | value 2 |
|  3 | geh | value 3 |
+----+-----+---------+
3 rows in set (0.00 sec)

Давайте добавим столбец элемента:

root@localhost [kris]> alter table overnormal add column item integer unsigned not null;
Query OK, 3 rows affected (0.48 sec)
Records: 3  Duplicates: 0  Warnings: 0

root@localhost [kris]> update overnormal set item = 1;
Query OK, 3 rows affected (0.01 sec)
Rows matched: 3  Changed: 3  Warnings: 0

root@localhost [kris]> insert into overnormal values (4, 'abc', 'item 1/1', 2), (5, 'def', 'item 1/2', 2), (6, 'geh', 'item 1/3', 2);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

root@localhost [kris]> select * from overnormal;
+----+-----+----------+------+
| id | k   | v        | item |
+----+-----+----------+------+
|  1 | abc | value 1  |    1 |
|  2 | def | value 2  |    1 |
|  3 | geh | value 3  |    1 |
|  4 | abc | item 1/1 |    2 |
|  5 | def | item 1/2 |    2 |
|  6 | geh | item 1/3 |    2 |
+----+-----+----------+------+
6 rows in set (0.00 sec)

Вы можете преобразовать это в традиционную таблицу, используя соединение смерти:

root@localhost [kris]> select t1.item, t1.v as abc, t2.v as def, t3.v as geh 
    from overnormal as t1 
    join overnormal as t2 
        on t1.item = t2.item 
       and t1.k = 'abc' 
       and t2.k = 'def' 
    join overnormal as t3 
        on t1.item = t3.item 
       and t3.k = 'geh';
+------+----------+----------+----------+
| item | abc      | def      | geh      |
+------+----------+----------+----------+
|    1 | value 1  | value 2  | value 3  |
|    2 | item 1/1 | item 1/2 | item 1/3 |
+------+----------+----------+----------+
2 rows in set (0.00 sec)

Вы можете отсортировать это обычным способом, используя предложение ORDER BY.

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

Вам лучше использовать модель данных, которая ближе к 3-й нормальной форме и менее близка к DKNF, и да, это возможно и менеепроблема, чем вы думаете.В любом случае вы не можете обрабатывать совершенно произвольные типы данных, не делая предположений о допустимых значениях k-значений, которые в любом случае являются законными и требуются в вашем приложении (или, если вы не делаете таких предположений, вы также можете сериализовать структуру в приложении и сохранитьклякса).

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