如何在MySQL中存储具有属性的唯一列表
我想在MySQL中存储如下数据,unique位于如何在MySQL中存储具有属性的唯一列表,mysql,sql,hibernate,database-design,rdbms,Mysql,Sql,Hibernate,Database Design,Rdbms,我想在MySQL中存储如下数据,unique位于user\u id和lids: recordid user_id lids length breadth ------------------------------------------------------------ 1 1 l1,l2 10 5 2 1 l1 7
user\u id
和lids
:
recordid user_id lids length breadth
------------------------------------------------------------
1 1 l1,l2 10 5
2 1 l1 7 5
3 1 l1,l3,l2 10 10
4 1 l2,l3 25 15
我的查询模式是:
- 给我长度和宽度,盖子是l2,l1
- 给我长度和宽度,盖子是l2,l3
用户id/lids
组合,从而在不进行大量字符串操作的情况下提供正确的长度和宽度
我想出了一个这样查询数据库的解决方案-
select * from table1 where find_in_set('l2', lids) AND find_in_set('l1', lids);
然后在代码中,将计数确定为精确的2个盖子。但这并不是完美的解决方案。需要关于它的指导
插件-一个SpringBoot+JPA(Hibernate)特定的解决方案将非常好,因为它不需要编写本机sql查询
如果我为
lids
-
recordid(fk) lid
----------------------------------
1 l1
1 l2
2 l1
3 l1
3 l3
3 l2
4 l2
4 l3
那么,我将如何确保只有一种独特的盖子组合可供用户使用?
我的选择查询是什么?会像下面这样吗
select * from table1, lids where main.recordid = lids.recordid and lid IN ('l2','l3');
中的操作符将运行或
查询,而不是和
,这也会给出错误的结果
我是否必须根据lids
表中的recordid
进行分组,然后应用where
条件?抱歉,我完全搞糊涂了,因为我读了很多与之相关的文章,分心了
好的,问题基本上是这样的-
我想查找具有要搜索的确切盖子列表的recordid。tl;dr:对于这样的设计问题,请考虑实体。关系,amd集合
您有两个实体,记录
和盖子
。他们有一种多对多的关系
让我们调用第二个表records\u lids
,以说明它是记录和lids之间的多对多关联表。它有两列,record\u id
和lid
。当该表中存在一行时,表示所述的记录id
具有所述的lid
该表的主键应由两列组成(记录id,lid)
。由于主键是唯一的,因此可以防止任何记录多次具有相同的盖子
现在,使用lidl1
查找记录id值集很容易。你甚至不需要第一张桌子
SELECT record_id FROM records_lids WHERE lid = `l1`
要查找具有多个lid的记录,需要获取记录集与每个lid的逻辑交点。你可以这样做:()
自然连接操作处理交叉操作;结果仅包括具有匹配的记录id
值的行。(其他一些型号的SQL table server有INTERSECT操作符,但还没有MySQL…)
您也可以这样做()
HAVING子句是您坚持想要所有三个盖子的记录的方式
一旦有了记录ID集,就可以将其加入到其他表中。()
或()
编辑:我没有完全理解你的问题。您想排除没有*精确(匹配的lid集)的记录。试试这个()。这取决于MySQL的一个怪癖,即像lid IN('l1','l2')
这样的布尔表达式在false时值为0,在true时值为1
SELECT *
FROM records
WHERE record_id IN (
SELECT record_id
FROM records_lids
GROUP BY record_id
HAVING SUM(lid IN ('l1', 'l2')) = 2
AND COUNT(*) = 2
)
SQL的核心是一种处理集合的语言
找出你的实体
找出他们之间的关系
了解如何获取所需的实体集
检索与集合匹配所需的行
对于像这样的设计问题,考虑实体、关系、amd集合
您有两个实体,记录
和盖子
。它们有多对多关系
让我们调用您的第二个表records\u lids
,以显示它是记录和lids之间的多对多关联表。它有两列,record\u id
和lid
。当该表中存在一行时,表示所提到的record\u id
具有所提到的lid
该表的主键应该由两列组成(record\u id,lid)
。由于主键是唯一的,因此可以防止任何记录多次具有相同的lid
现在,用lidl1
查找记录id值集很容易。您甚至不需要第一个表
SELECT record_id FROM records_lids WHERE lid = `l1`
要查找具有多个lid的记录,您需要获取记录集与每个lid的逻辑交集
自然联接操作处理交集操作;结果仅包括具有匹配的记录id
值的行。(SQL table server的一些其他版本具有INTERSECT运算符,但还没有MySQL…)
您也可以这样做()
HAVING子句是您坚持想要所有三个盖子的记录的方式
一旦有了记录ID集,就可以将其加入到其他表中。()
或()
编辑:我没有完全理解你的问题。你想排除没有*精确(匹配的lid集)的记录。试试这个()。这取决于MySQL的一个怪癖,这就是像('l1','l2')
中的lid这样的布尔表达式的值在false时为0,在true时为1
SELECT *
FROM records
WHERE record_id IN (
SELECT record_id
FROM records_lids
GROUP BY record_id
HAVING SUM(lid IN ('l1', 'l2')) = 2
AND COUNT(*) = 2
)
SQL的核心是一种处理集合的语言
找出你的实体
找出他们之间的关系
了解如何获取所需的实体集
检索与集合匹配所需的行
规范化数据。每行存储一个盖子。清除CSV数据。这只会导致
SELECT *
FROM records
WHERE record_id IN (
SELECT record_id
FROM records_lids
WHERE lid IN ('l1','l2','l3')
GROUP BY record_id
HAVING COUNT(*) = 3
)
SELECT *
FROM records
WHERE record_id IN (
SELECT record_id
FROM records_lids
GROUP BY record_id
HAVING SUM(lid IN ('l1', 'l2')) = 2
AND COUNT(*) = 2
)