Database 如何实现多对多对多数据库关系?
我正在构建一个SQLite数据库,不知道如何继续这个场景 我将用一个真实的例子来解释我需要什么: 我有一个产品清单,在各个州的许多商店都有销售。并非每个Database 如何实现多对多对多数据库关系?,database,sqlite,many-to-many,Database,Sqlite,Many To Many,我正在构建一个SQLite数据库,不知道如何继续这个场景 我将用一个真实的例子来解释我需要什么: 我有一个产品清单,在各个州的许多商店都有销售。并非每个商店都销售特定的产品,而那些销售特定产品的商店可能只在一种状态下出售。大多数商店在大多数州销售一种产品,但不是全部 比如说,我想在夏威夷买一台真空吸尘器。乔的硬件在18个州销售真空吸尘器,但不在夏威夷。沃尔玛在夏威夷销售真空吸尘器,但不销售微波炉。汉堡王一点也不卖吸尘器,但在美国任何地方都会给我一个大汉堡 所以,如果我在夏威夷寻找一个真空地带,我
商店
都销售特定的产品
,而那些销售特定产品的商店可能只在一种状态下出售。大多数商店在大多数州销售一种产品,但不是全部
比如说,我想在夏威夷买一台真空吸尘器。乔的硬件在18个州销售真空吸尘器,但不在夏威夷。沃尔玛在夏威夷销售真空吸尘器,但不销售微波炉。汉堡王一点也不卖吸尘器,但在美国任何地方都会给我一个大汉堡
所以,如果我在夏威夷寻找一个真空地带,我应该只能得到沃尔玛。虽然其他商店可能出售真空吸尘器,也可能在夏威夷出售,但它们不同时出售,但沃尔玛会
如何在关系数据库中高效地创建这种类型的关系(具体来说,我目前正在使用SQLite,但将来需要能够转换为MySQL)
显然,我需要产品
、存储
和状态
的表,但我不知道如何创建和查询适当的联接表
例如,如果我查询某个产品
,我将如何确定哪个商店
将在特定的州
销售该产品,记住沃尔玛可能不会在夏威夷销售吸尘器,但他们确实在那里销售茶叶
我了解RD中1:1、1:n和M:n关系的基本知识,但我不确定在多对多的情况下如何处理这种复杂性
如果您能展示一些SQL语句(或DDL)来演示这一点,我将非常感激。谢谢大家! 您需要创建产品、状态和存储的组合映射表,作为tbl_product_states_stores
,它将存储产品、状态和存储的映射。这些列将是id
,product\u id
,state\u id
,stores\u id
一种公认的常用方法是使用一个表格,其中一列用于参考产品,另一列用于商店。这样的表有很多名称,比如引用表、关联表、映射表等等
您希望这些是有效的,因此请尝试使用一个数字来引用,当然,该数字必须唯一地标识它引用的内容。默认情况下,使用SQLite时,表有一个特殊的列,通常是隐藏的,这是一个唯一的数字。它是rowid,并且通常是访问行的最有效的方式,因为SQLite是为这种常见用法而设计的
SQLite允许您为每个表创建一个列,该列是行id的别名您只需提供列,后跟整型主键
,并且通常需要命名列id
因此,利用这些信息,参考表将有一列用于产品id,另一列用于商店id,以满足每种产品/商店组合的需要
例如,创建了三个表(存储产品和一个参考/映射表),前者使用以下方式填充:-
CREATE TABLE IF NOT EXISTS _products(id INTEGER PRIMARY KEY, productname TEXT, productcost REAL);
CREATE TABLE IF NOT EXISTS _stores (id INTEGER PRIMARY KEY, storename TEXT);
CREATE TABLE IF NOT EXISTS _product_store_relationships (storereference INTEGER, productreference INTEGER);
INSERT INTO _products (productname,productcost) VALUES
('thingummy',25.30),
('Sky Hook',56.90),
('Tartan Paint',100.34),
('Spirit Level Bubbles - Large', 10.43),
('Spirit Level bubbles - Small',7.77)
;
INSERT INTO _stores (storename) VALUES
('Acme'),
('Shops-R-Them'),
('Harrods'),
('X-Mart')
;
结果表为:-
- \u产品\商店\关系将为空
将产品放入商店(例如)可通过以下方式完成:-
-- Build some relationships/references/mappings
INSERT INTO _product_store_relationships VALUES
(2,2), -- Sky Hooks are in Shops-R-Them
(2,4), -- Sky Hooks in x-Mart
(1,3), -- thingummys in Harrods
(1,1), -- and Acme
(1,2), -- and Shops-R-Them
(4,4), -- Spirit Level Bubbles Large in X-Mart
(5,4), -- Spiirit Level Bubble Small in X-Mart
(3,3) -- Tartn paint in Harrods
;
\u产品与商店的关系将是:-
下面这样的查询将列出按门店和产品排序的门店中的产品:-
SELECT storename, productname, productcost FROM _stores
JOIN _product_store_relationships ON _stores.id = storereference
JOIN _products ON _product_store_relationships.productreference = _products.id
ORDER BY storename, productname
;
结果输出为:-
此查询将仅列出产品名称包含s或s(通常区分大小写)的门店,输出将按照ASC中的productcost结束顺序排序,然后是storename,然后是productname:-
SELECT storename, productname, productcost FROM _stores
JOIN _product_store_relationships ON _stores.id = storereference
JOIN _products ON _product_store_relationships.productreference = _products.id
WHERE productname LIKE '%s%'
ORDER BY productcost,storename, productname
;
输出:-
扩展以上考虑状态。
2个新表状态和存储状态参考
虽然不需要一个参考表(一个商店只有一个状态,除非你考虑一个连锁店是一个商店,在这种情况下,这也将应付)
SQL可以是:-
CREATE TABLE IF NOT EXISTS _states (id INTEGER PRIMARY KEY, statename TEXT);
INSERT INTO _states (statename) VALUES
('Texas'),
('Ohio'),
('Alabama'),
('Queensland'),
('New South Wales')
;
CREATE TABLE IF NOT EXISTS _store_state_references (storereference, statereference);
INSERT INTO _store_state_references VALUES
(1,1),
(2,5),
(3,1),
(4,3)
;
如果运行了以下查询:-
SELECT storename,productname,productcost,statename
FROM _stores
JOIN _store_state_references ON _stores.id = _store_state_references.storereference
JOIN _states ON _store_state_references.statereference =_states.id
JOIN _product_store_relationships ON _stores.id = _product_store_relationships.storereference
JOIN _products ON _product_store_relationships.productreference = _products.id
WHERE statename = 'Texas' AND productname = 'Sky Hook'
;
产出将是:-
CREATE TABLE IF NOT EXISTS _states (id INTEGER PRIMARY KEY, statename TEXT);
INSERT INTO _states (statename) VALUES
('Texas'),
('Ohio'),
('Alabama'),
('Queensland'),
('New South Wales')
;
CREATE TABLE IF NOT EXISTS _store_state_references (storereference, statereference);
INSERT INTO _store_state_references VALUES
(1,1),
(2,5),
(3,1),
(4,3)
;
如果没有WHERE条款:-
使Stores-R-Them在所有州都有业务:-
以下内容将使Stores-R-Them在所有州都有业务:-
INSERT INTO _store_state_references VALUES
(2,1),(2,2),(2,3),(2,4)
;
现在,德克萨斯州的Sky Hook的结果是:-
- 请注意,本部分仅介绍本主题的基础知识
谢谢你的回复,迈克!不幸的是,这并不能解决原始问题中的第三维度问题:特定商店销售产品的特定状态…请放心,我将添加一个状态表并将其关联起来。谢谢你的更新,Mike!然而,我认为这并不能解决问题。商店可能在几个州销售产品,但这种结构使商店(及其销售的所有产品)只能在一个州销售。您是否看到题为“以下内容将使商店-R-他们在所有州都有业务”的最后一部分:-?将查询更改为WHERE statename='Alabama'和productname='Sky Hook'
将列出Stores-R-Them,因为_store\u state\u引用有一个条目(2,3)(storereference为2(Stores-R-Them),stateference为3(Alabama))。限制是一家商店在所有地点都有相同的产品。如果你想让各个商店拥有不同的产品,那么你可以在阿拉巴马州、得克萨斯州等地开设商店。是的,我看到了,但正如你所说,这将假设商店在所有州都提供相同的产品,但事实并非如此。例如,他们可能在加利福尼亚州提供天空挂钩,但在纽约不提供。