Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MySql在一个单元格中存储另一个表的多个引用并选择它?_Php_Mysql_Select - Fatal编程技术网

Php MySql在一个单元格中存储另一个表的多个引用并选择它?

Php MySql在一个单元格中存储另一个表的多个引用并选择它?,php,mysql,select,Php,Mysql,Select,我有两张桌子 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 - 这是一个简单的例子,表货物实际上很长,人中的每个人都可以有多个货物分配给他,例如汽车、船、糖等。没有限制一个人可以拥有多少,而且完全是随机的。我找不到比单独存储更好的方法,例如1,5,3 我在选择我需要的东西时遇到了问题 SELECT people.*, goods.name

我有两张桌子

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
-

这是一个简单的例子,表
货物
实际上很长,
中的每个人都可以有多个
货物
分配给他,例如汽车、船、糖等。没有限制一个人可以拥有多少,而且完全是随机的。我找不到比单独存储更好的方法,例如
1,5,3

我在选择我需要的东西时遇到了问题

SELECT people.*, goods.name
   FROM people
      LEFT JOIN  goods ON goods.g_id = people.goods_owned
         WHERE name = "Sam"
但问题是,您拥有的商品在单元格中有多个商品ID,需要对它们进行分解才能得到答案:

1, Sam, sugar, car, salt

如果您知道在一个单元格中存储(例如100个)多个值的更好方法,请告诉我

您的数据库未规范化。你有。如果可能的话,您应该规范化您的数据库

如果无法更改数据库设计,则可以使用,但会很慢:

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'

一个人可以与零个、一个或多个商品相关。 一个好的关系可以是零人、一人或多人

这是一种多对多的关系

通常,我们通过创建第三个表来处理这个问题,这是一个指向其他两个表的“关系”

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    
这两列的组合可以指定为唯一,并可以用作表的主键。每个列都可以定义为父表的外键

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)
) ;

另一种选择是,如果“goods”集合是静态的、定义良好的,并且不需要在表中表示,那么您可以使用MySQL集合数据类型,并拥有一个表。但这种方法只适用于静态设置(无需更改)。

我只是觉得很无聊

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;
        ;

糟糕的表格设计,数据正常化。添加商品\u拥有的表格人员\u id、良好\u id、每个商品一行也-不良表格设计,使数据正常化。添加商品\u拥有的表人物\u id,good\u id,每种商品一行:)阅读多对多关系,您需要在此处添加唯一的
id
作为主键,为您的表示例自动递增。非常感谢。我知道我以前是这样做的,就在今天,我有点脑死亡。当你不得不重建所有的原始布局时,你很难找到替代方案,你通常会试图找到解决方案。这一切都是从每人一个好的开始的,所以我把它放在同一张桌子上。@JTSmith,为什么?您可以在这两个字段上添加一个键以实现相同的效果result@JT史密斯:不需要id列。两个外键的组合可用作主键。如果此表包含其他列(记录不存在关系的信息),则我同意您的意见,并选择添加匿名ID值。Thx对于FIND_IN_SET,我不知道ITW…感谢“如果您无法更改数据库…”。我经常问一个问题,得到很多答案,假设我有幸重新设计从应用程序到网络架构的一切,lol.+1。干得好。如何使用InnoDB引擎并指定外键约束?如果有一组静态的类,这将是MySQL枚举(enumeration)数据类型的候选,而不需要单独的表。任何改进-我刚刚打开编辑器并使用默认值,这些类就是您描述的食物、栖息地和交通。通过一个表,您可以按类选择/排序,以及添加/更改类。e、 g.如果您想拥有飞机、火车和汽车,而不仅仅是运输,您可以将这些类添加到该表中,并更改货物表中用于这些项目的id。
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;
        ;