Вопрос эффективности - выбор числовых данных из одного поля - PullRequest
0 голосов
/ 18 февраля 2011

У меня есть пара таблиц, и мне нужно искать числовые значения в Таблице1, которые соответствуют связанным идентификаторам в Таблице2.Например:

Table1

ID | Item
1    Cat
3    Frog
9    Dog
11   Horse

Table2

Category | Contains
Group 1   1
Group 2   3|9
Group 3   3|9|11

Первоначально я думал, что LIKE будет работать, но если бы я искал "1", я быв конечном итоге соответствует «11».Я посмотрел на SET, но в документации по MySQL указано, что максимальное количество элементов равно 64, и у меня более 200 строк элементов в Таблице 1.Я мог бы обернуть каждый идентификатор элемента символом (например, «| 1 |»), но это не очень эффективно.У каждой группы будут уникальные предметы (например, в одной группе не будет двух кошек).

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

Другой вариант, который у меня есть, - разделить Содержимое на 6 отдельных столбцов, поскольку в группе никогда не будет более 6 элементов, но тогда я не уверенКак искать во всех 6 столбцах, не полагаясь на шесть запросов ИЛИ:

Category |  C1  |  C2  |  C3  |  C4 (etc)
Group 1    1      null   null   null
Group 2    3       9     null   null
Group 3    3       9      11    null

SELECT * FROM Table2 WHERE C1 = '1' OR C2 = '1' OR C3 = '1' etc.

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

Ответы [ 5 ]

1 голос
/ 18 февраля 2011

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

Реально то, что вы моделируете, является отношением "многие ко многим" между таблицей 1 и таблицей 2. Это означает, что одна строка в table1 может быть связана со многими строками в table2, и наоборот.

Чтобы создать такой тип отношений, вам нужна третья таблица, которую мы можем сейчас назвать rel_table1_table2.

rel_table1_table2 будет содержать только значения первичного ключа из двух связанных таблиц, которые в этом случае представляются как table1.ID и table2.Category.

Если вы хотите связать строку в table1 со строкой в ​​table2, вы должны добавить строку в rel_table1_table2 со значениями первичного ключа из table1 и table2 соответственно.

Пример:

INSERT INTO rel_table1_table2 (ID, Category) VALUES (1, "Group 1")

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

SELECT i.Item from table1 t1 join rel_table1_table2 r on t1.ID=r.ID join table2 t2 on r.Category=t2.Category WHERE t2.Category="Group 3"

Имеет ли это смысл?

0 голосов
/ 18 февраля 2011

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

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

Таблица 1

ID | Item
1    Cat
3    Frog
9    Dog
11   Horse

Таблица 2

Category | Contains
Group 1    1
Group 2    3
Group 2    9
Group 3    3
Group 3    9
Group 3    11

Теперь, когда вы хотите узнать "Какие элементы содержит группа 2?", вы можете написать запрос для того, который выбирает все строки категории" Группа 2 "из таблицы 2. Когда вы хотите выяснить," Как называется элемент 9 ", вы можете написать запрос, который выбирает строкуиз таблицы 1.

0 голосов
/ 18 февраля 2011

Перерыв Table2.Contains в другой таблице, которая объединяет Item и Category:

Item         Item_Category           Category
------       --------------          ---------
ID (1)----(*)ItemID                  Name
Name         CategoryID(*)-------(1) ID

Теперь ваш запрос будет выглядеть так:

SELECT Category.* FROM Category, Item_Category
WHERE (Item_Category.CategoryID = Category.ID)
  AND (Item_Category.ItemID IN (1, 2, 3, 11))
0 голосов
/ 18 февраля 2011

Эта «новая» таблица будет содержать по одной строке для каждой категории, к которой относится животное.

create table animal(
   animal_id
  ,name
  ,primary key(animal_id)
)

create table category(
   category_id
  ,name
  ,primary key(category_id)
)

create table animal_categories(
   animal_id
  ,category_id
  ,primary key(animal_id, category_id) 
)

Для данных вашего примера таблица animal_categories будет содержать:

   category_id | animal_id  
   +-----------+------------+
   |     1     |       1    |
   |     2     |       3    |
   |     2     |       9    |
   |     3     |       3    |
   |     3     |       9    |
   |     3     |      11    |
   +-----------+------------+
0 голосов
/ 18 февраля 2011

Вместо использования «лайк» используйте «REGEXP», чтобы вы не получили «11» при поиске «1»

...