Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.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/6/cplusplus/159.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
Database 如何实现多对多对多数据库关系?_Database_Sqlite_Many To Many - Fatal编程技术网

Database 如何实现多对多对多数据库关系?

Database 如何实现多对多对多数据库关系?,database,sqlite,many-to-many,Database,Sqlite,Many To Many,我正在构建一个SQLite数据库,不知道如何继续这个场景 我将用一个真实的例子来解释我需要什么: 我有一个产品清单,在各个州的许多商店都有销售。并非每个商店都销售特定的产品,而那些销售特定产品的商店可能只在一种状态下出售。大多数商店在大多数州销售一种产品,但不是全部 比如说,我想在夏威夷买一台真空吸尘器。乔的硬件在18个州销售真空吸尘器,但不在夏威夷。沃尔玛在夏威夷销售真空吸尘器,但不销售微波炉。汉堡王一点也不卖吸尘器,但在美国任何地方都会给我一个大汉堡 所以,如果我在夏威夷寻找一个真空地带,我

我正在构建一个SQLite数据库,不知道如何继续这个场景

我将用一个真实的例子来解释我需要什么:

我有一个产品清单,在各个州的许多商店都有销售。并非每个
商店
都销售特定的
产品
,而那些销售特定产品的商店可能只在一种
状态下出售。大多数商店在大多数州销售一种产品,但不是全部

比如说,我想在夏威夷买一台真空吸尘器。乔的硬件在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
;
结果输出为:-

此查询将仅列出产品名称包含ss(通常区分大小写)的门店,输出将按照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))。限制是一家商店在所有地点都有相同的产品。如果你想让各个商店拥有不同的产品,那么你可以在阿拉巴马州、得克萨斯州等地开设商店。是的,我看到了,但正如你所说,这将假设商店在所有州都提供相同的产品,但事实并非如此。例如,他们可能在加利福尼亚州提供天空挂钩,但在纽约不提供。