5

私は2つのテーブルを持っています

table: people 

id name goods_owned
1  john   1,4,3
2  Mike   2,5
3  Sam    1,5,2
4  Andy   5,3,4

-

table goods:

  g_id g_name  g_class
    1   sugar  food
    2   salt   food
    3   boat   transp
    4   house  habitation
    5   car    transp

これはテーブルの簡単な例ですがgoods、実際には非常に長く、各人にpeople複数goodsを割り当てることができます。たとえば、車、ボート、砂糖など、1 人が持つことができる量に制限はなく、完全にランダムです。コマ区切りよりも良い保管方法が見つかりませんでした。1,5,3

必要な選択を行うのに問題があります。

SELECT people.*, goods.name
   FROM people
      LEFT JOIN  goods ON goods.g_id = people.goods_owned
         WHERE name = "Sam"

ただし、問題は、goods_owned がセル内に商品の複数の ID を持ち、回答を得るためにそれらを何らかの方法で分解する必要があることです。

1, Sam, sugar, car, salt

複数の値 (たとえば 100) を 1 つのセルにコンマで区切って格納するよりも良い方法を知っている場合は、お知らせください。

4

3 に答える 3

3

人は、ゼロ、1つ、または複数の商品に関連付けることができます。良いものは、ゼロ、1人または複数の人に関連付けることができます。

それは多対多の関係です。

通常、これを処理するには、他の2つのテーブルを指す「関係」である3番目のテーブルを作成します。

table: goods_owned
people_id goods_id
        1        1
        1        4
        1        3
        2        2
        2        5
        3        1
        3        5
        3        2
        4        5
        4        3
        4        4    

これらの2つの列の組み合わせは、一意として指定でき、テーブルの主キーとして機能できます。各列は、親テーブルへの外部キーとして定義できます。

CREATE TABLE goods_owned
( people_id  INT UNSIGNED NOT NULL
, goods_id   INT UNSIGNED NOT NULL
, PRIMARY KEY (people_id, goods_id)
-- , KEY FK_goods_owned_people (people_id)  -- redundant with PK
, KEY FK_goods_owned_goods (goods_id)
, CONSTRAINT FK_goods_owned_people FOREIGN KEY (people_id) REFERENCES people (id)
, CONSTRAINT FK_goods_owned_goods FOREIGN KEY (goods_id) REFERENCES goods (g_id)
) ;

別の方法として、「商品」のセットが静的で明確に定義されており、テーブルで表す必要がない場合は、MySQL SETデータ型を利用して、単一のテーブルを作成できます。ただし、このアプローチは、セットが静的である場合にのみ適しています(変更する必要はありません)。

于 2012-05-16T23:51:54.420 に答える
2

データベースは正規化されていません。列内に繰り返しグループがあります。可能であれば、データベースを正規化する必要があります。

データベースの設計を変更できない場合は使用できますがFIND_IN_SET、sloooooooowになります。

SELECT people.id, people.name, people.goods_owned, goods.name
FROM people
LEFT JOIN goods ON FIND_IN_SET(goods.g_id, people.goods_owned)
WHERE name = 'Sam'
于 2012-05-16T23:46:13.693 に答える
1

本当に退屈だっただけにしましょう...

CREATE TABLE `people` (
  `id` int(11) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
;
CREATE TABLE `goods` (
  `id` int(11) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `class_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
;
CREATE TABLE `goods_owned` (
  `people_id` INT(11) DEFAULT NULL,
  `goods_id` INT(11) DEFAULT NULL
) ENGINE=MYISAM CHARSET=latin1
;
CREATE TABLE `classes` (
  `id` int(11) NOT NULL,
  `class_name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
;

INSERT INTO `people` (`id`, `name`) VALUES('1','John');
INSERT INTO `people` (`id`, `name`) VALUES('2','Mike');
INSERT INTO `people` (`id`, `name`) VALUES('3','Sam');
INSERT INTO `people` (`id`, `name`) VALUES('4','Andy');

INSERT INTO `classes` (`id`, `class_name`) VALUES('1','Food');
INSERT INTO `classes` (`id`, `class_name`) VALUES('2','Trans');
INSERT INTO `classes` (`id`, `class_name`) VALUES('3','Habitation');

INSERT INTO `goods` (`id`, `name`, `class_id`) VALUES('1','Sugar','1');
INSERT INTO `goods` (`id`, `name`, `class_id`) VALUES('2','Salt','1');
INSERT INTO `goods` (`id`, `name`, `class_id`) VALUES('3','Boat','2');
INSERT INTO `goods` (`id`, `name`, `class_id`) VALUES('4','House','3');
INSERT INTO `goods` (`id`, `name`, `class_id`) VALUES('5','Car','2');

INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('1','1');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('1','4');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('1','3');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('2','2');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('2','5');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('3','1');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('3','5');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('3','2');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('4','5');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('4','3');
INSERT INTO `goods_owned` (`people_id`, `goods_id`) VALUES('4','4');

SELECT
    people.name
    , goods.name
    , classes.class_name
FROM people
    LEFT JOIN goods_owned ON (people.id = goods_owned.people_id)
    LEFT JOIN goods ON (goods_owned.goods_id = goods.id)
    LEFT JOIN classes ON (goods.class_id = classes.id)
WHERE classes.id = 1  /*Include only Food Goods*/
ORDER BY people.name;
        ;
于 2012-05-16T23:59:29.017 に答える