sqlite 列为列表或集合的SQL数据库

snz8szmq  于 2022-11-14  发布在  SQLite
关注(0)|答案(4)|浏览(231)

对于SQL数据库(在我的例子中是Sqlite,使用的是Python),拥有一组元素的列的标准方式是什么?

id  name       items_set
1   Foo        apples,oranges,tomatoes,ananas
2   Bar        tomatoes,bananas
...

一个简单的实现是使用

CREATE TABLE data(id int, name text, items_set text);

但也有几个缺点:

  • 要查询所有包含ananas的行,我们必须使用items_set LIKE '%ananas%'和一些带有分隔符的技巧,以避免查询“ananas”也返回包含“bananas”的行,等等。
  • 当我们在一行中插入一个新项时,我们必须加载整个items_set,并查看该项是否已经在列表中,然后在末尾连接,newitem

当然还有更好的解决方案,什么是针对列表或集合的列的标准SQL解决方案?
注意:我事先不知道集合/列表的所有可能值。
我可以看到一个带有几个附加表的解决方案,但在我的测试中,它将磁盘上的大小乘以x2或x3倍,这对于许多GB的数据来说是一个问题。
有没有更好的解决方案?

wwwo4jvm

wwwo4jvm1#

要拥有结构良好的SQL数据库,您应该将项提取到它们自己的表中,并在主表和items表之间使用连接表
我不熟悉Sqlite语法,但您应该能够使用以下命令创建表

CREATE TABLE entities(id int, name text);  
CREATE TABLE entity_items(entity_id int, item_id int);  
CREATE TABLE items(id int, name text);

添加数据

INSERT INTO entities (name) VALUES ('Foo'), ('Bar');  
INSERT INTO items (name) VALUES ('tomatoes'), ('ananas'), ('bananas');  
INSERT INTO entity_items (entity_id, item_id) VALUES (
  (SELECT id from entities WHERE name='Foo'),
  (SELECT id from items WHERE name='bananas')
);

查询数据

SELECT * FROM entities
LEFT JOIN entity_items
ON entities.id = entity_items.entity_id
LEFT JOIN items
ON items.id = entity_items.item_id
WHERE items.name = 'bananas';
wvt8vs2t

wvt8vs2t2#

你可能有两个选择。一种更传统的标准方法是多对多关系。例如,您有三个表,分别是Employees、Projects和ProjectEmployees。后者描述了您的多对多关系(每个员工可以处理多个项目,每个项目有一个团队)。
在单个值中设置一个集合会使表变得不规范,无论哪种情况,都会使事情复杂化。但如果您只是使用JSON格式和SQLite提供的JSON功能。如果您的SQLite版本不是最新的,那么它可能没有内置JSON扩展。您需要更新(最佳选择)或动态加载JSON扩展。不确定是否可以使用随Python提供的SQLite副本来执行此操作。

46scxncf

46scxncf3#

为了详细说明@ussu所说的内容,理想情况下,您的表应为每个Things&Items对一行,使用ID而不是名称:

id  thing_id   item_id
1   1          1
2   1          2
3   1          3
4   1          4
5   2          3
5   2          4

然后查找物品和物品名称的查询表:

id  name
1   Foo
2   Bar

id  name
1   apples
2   oranges
3   tomatoes
4   bananas
g2ieeal7

g2ieeal74#

在MySQL中,您有set类型
创作:

CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));

选择:

mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';

插入:

INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');

相关问题