2013-09-13 1 views
1

Я хотел бы создать базу данных продуктов. Каждый продукт имеет характеристики, описываемые как массив значений x и соответствующих значений y. И я хотел бы запросить продукты по определенным характеристикам.Запрос пары XY массива для значения y при произвольном x в SQL

Пример данных продукта:

ProductA_x = [10, 20, 30, 40, 50] 
ProductA_y = [2, 10, 30, 43, 49] 

ProductB_x = [11, 22, 33, 44, 55, 66] 
ProductB_y = [13, 20, 42, 35, 28, 21] 

Теперь я хотел бы получить список продуктов, где у < 35 @ х = 31. В примере случае, я должен получить ProductA.

  • Если я использую MySQL, что было бы хорошим способом определить таблицу (ы) для достижения этого запроса на уровне SQL?
  • Стало бы легче, если бы я мог использовать PostgreSQL? (Используйте массив или типа JSON ??)

Один из способов мне посоветовали был составить таблицу для определения х пар для й диапазона. Первые данные для диапазона x [0] - x [1], следующие данные для x [1] - x [2]. Что-то вроде этого.

| ProductID | x1 | x2 | y1 | y2 | 
| --------- | -- | -- | -- | -- | 
| 1 | 10 | 20 | 2 | 10 | 
| 1 | 20 | 30 | 10 | 30 | 
| 1 | 30 | 40 | 30 | 43 | 
| 1 | 40 | 50 | 43 | 49 | 
| 2 | 11 | 22 | 33 | 44 | 
| 2 | 22 | 33 | 20 | 42 | 
| 2 | 33 | 44 | 42 | 35 | 
| 2 | 44 | 55 | 35 | 28 | 
| 2 | 55 | 66 | 28 | 21 | 

Тогда я мог бы запросить (x1> 31 и 31 < x2) и (y1 < 35 ИЛИ у2 < 35)

Это решение не слишком плохо, но интересно, если есть поумнее подход.

Обратите внимание: массив x гарантированно будет инкрементным, но другой продукт будет иметь различное начальное значение x, размер шага и количество точек. И значение x для поиска может не существовать как точное значение в массиве x. Длина реальных массивов x и y будет около 2000. Я ожидаю, что у меня будет около 10 000 продуктов.

Было бы лучше, если соответствующее значение y можно интерполировать, но поиск значения y с ближайшим значением x является приемлемым.

ответ

0

поскольку каждый X соответствует ровно одна Y, в здравом уме определение таблицы на классической реляционной базы данных будет:

CREATE TABLE product (id serial not null unique, sku text primary key, ....); 
CREATE TABLE product_xy (product_id int not null references product(id), 
         x int not null, 
         y int not null, 
         primary key(product_id, x)); 

Это сделает ваш запрос управляемым во всех случаях.

На PostgreSQL 9.3 вы можете использовать LATERAL-подзапрос, чтобы эффективно использовать массивы, но я не думаю, что это будет проще, чем просто начать с реляционного дизайна. Единственный случай, когда вы захотите сохранить информацию в массиве в PostgreSQL, - это то, что значение ординальности имеет значение для массива x. Тогда конструкция становится немного более сложным, поскольку следующие комбинации массива являются семантически не то же самое:

array[1, 2, 3] x 
array[4, 5, 6] y 

и

array[2, 1, 3] x 
array[5, 4, 6] y 

Если те, должны быть различны, то идти с массива на основе решения в PostgreSQL (обратите внимание, что в обоих случаях одно и то же значение x соответствует одному и тому же значению y, но порядок пар отличается). В противном случае используйте стандартный реляционный дизайн.Если вы должны идти с этим, то ваш лучший вариант должен иметь 2-мерную ху массив, который будет что-то вроде:

array[ 
    array[1, 2, 3], 
    array[4, 5, 6] 
] xy 

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

Смежные вопросы