Database Oracle/mySQL数据库

Database Oracle/mySQL数据库,database,database-design,many-to-many,data-modeling,Database,Database Design,Many To Many,Data Modeling,我是数据库新手,我需要解决这个问题: client(NAME, CITY, STREET, NUMBER, BALANCE, CLIENT_CODE); order(ORDER_NUMBER, CLIENT_CODE, PROVIDER_NAME, FUEL, QTY, DATE); provider(PROVIDER_NAME, PROVIDER_ADRESS, FUEL_CODE, PRICE, STOCK); fuel(FUEL_CODE, FUEL_NAME); 为了解决多对多关系,我

我是数据库新手,我需要解决这个问题:

client(NAME, CITY, STREET, NUMBER, BALANCE, CLIENT_CODE);
order(ORDER_NUMBER, CLIENT_CODE, PROVIDER_NAME, FUEL, QTY, DATE);
provider(PROVIDER_NAME, PROVIDER_ADRESS, FUEL_CODE, PRICE, STOCK);
fuel(FUEL_CODE, FUEL_NAME);
为了解决多对多关系,我已经尝试(并且我猜已经成功)为provider和fuel创建一个名为provider\u fuel的ALTER表,但我不知道如何在order和provider之间创建连接

我更改了如下实体:

provider(PROVIDER_ID, PROVIDER_ADRESS);
fuel(FUEL_CODE, FUEL_NAME);
provider_fuel(ID_ENTRY, ID_PROVIDER, ID_FUEL, PRICE, STOCK).
SELECT od.* FROM order od, provider pd WHERE od.provider_name=pd.provider_name 
这样行吗?如果是这样,我如何在数据库中的所有实体之间建立连接


我必须提到的是,我的应用程序应该允许客户从拥有特定燃料、价格等的供应商处下单。

您可以将id\u供应商放入订单表,并通过id获取供应商详细信息。例如

Select *,p.price,p.fuel_code from order as o join provider as p on o.id_provider=p.id

欢迎来到Oracle数据库世界

可以使用联接结构在表或视图之间建立连接

在您的示例中,可以如下方式连接表:

provider(PROVIDER_ID, PROVIDER_ADRESS);
fuel(FUEL_CODE, FUEL_NAME);
provider_fuel(ID_ENTRY, ID_PROVIDER, ID_FUEL, PRICE, STOCK).
SELECT od.* FROM order od, provider pd WHERE od.provider_name=pd.provider_name 
或者你可以这样写。这取决于你的风格。但是我更喜欢第一个

SELECT od.* FROM order od INNER JOIN provider pd ON od.provider_name=pd.provider_name
但在联接中使用数字类型列总是更好的。所以我建议,在两个表上创建provider_id(数字类型),并将它们连接起来


SQL中有5种主要的联接类型(内部联接、外部联接、完全联接、左侧联接、右侧联接)。它们各自提供了不同的东西

我建议以下表格布局:

address(ID_ADDRESS, CITY, STREET, NUMBER);

client(ID_CLIENT, NAME, ID_ADDRESS);

client_order(ID_CLIENT_ORDER, ID_CLIENT, RECEIVED_DATE);

client_order_detail(ID_CLIENT_ORDER_DETAIL, ID_CLIENT_ORDER, ID_PROVIDER, ID_PRODUCT,
                    ORDER_QTY, STATUS, DELIVERED_DATE);  -- Status in ('OPEN', 'DELIVERED')

provider(ID_PROVIDER, NAME, ID_ADDRESS);

product(ID_PRODUCT, PRODUCT_NAME);

provider_product(ID_PROVIDER, ID_PRODUCT, PRICE, STOCK_QTY);
你可以,如果你愿意,扩展这个。例如,一个提供者可能有多个位置,可以从这些位置提供产品,在这种情况下,您需要将单个提供者表重新工作到类似的位置

PROVIDER(ID_PROVIDER, NAME)

PROVIDER_PRODUCT(ID_PROVIDER, ID_PRODUCT, PRICE)

PROVIDER_ADDRESS(ID_PROVIDER_ADDRESS, ID_PROVIDER, ID_ADDRESS)
然后根据需要对产品进行返工

PROVIDER_ADDRESS_PRODUCT(ID_PROVIDER_ADDRESS, ID_PRODUCT, STOCK_QTY)
我认为供应商收取的价格也可能取决于其发货地点,因此您可能需要更改型号以适应这种情况。关键是,有很多不同的方法可以做到这一点,这在很大程度上取决于您的需求

编辑 要使用上面的表获取订单的总值,可以使用以下查询:

SELECT co.ID_CLIENT_ORDER, SUM(cod.ORDER_QTY * pp.PRICE) AS ORDER_TOTAL_VALUE
  FROM CLIENT_ORDER co
  INNER JOIN CLIENT_ORDER_DETAIL cod
    ON cod.ID_CLIENT_ORDER = co.ID_CLIENT_ORDER
  INNER JOIN PROVIDER_PRODUCT pp
    ON pp.ID_PROVIDER = cod.ID_PROVIDER AND
       pp.ID_PRODUCT = cod.ID_PRODUCT
  GROUP BY co.ID_CLIENT_ORDER
  ORDER BY co.ID_CLIENT_ORDER

如果我理解正确,您的数据库代表了一个市场,客户可以从供应商处购买不同种类的燃料。到目前为止,您已经使用了自然关键点:

  • 客户端有一些识别它们的登录代码(客户端代码)
  • 提供者由其名称标识。你想要这个吗?这意味着提供者地址保持不变,不能更改。这可能是也可能不是所希望的。如果公司JACOB的FUELSHOP INC变更为FUELSHOP INC,您希望将其视为同一家公司还是不同的公司
  • 您还可以生成订单号。您希望它们在数据库中是唯一的,还是每个客户端或每个提供者都唯一?相应地,订单表的键可以是订单号或订单号+客户代码或订单号+供应商名称
现在你不想让一家供应商只销售一种燃料,而是销售各种类型的燃料。你介绍了一个桥牌桌。但在同一步骤中,您将引入技术ID。是否要使用技术ID而不是自然密钥

您有提供者(提供者ID、提供者地址),其中提供者的名称缺失或包含在地址中。这允许您以后更改名称。但请记住,您可能希望在每次订单中存储该名称,因为您可能希望稍后重新打印该名称,或者只是说您是向法律公司JACOB’S FUELSHOP INC.还是FUELSHOP INC.下订单。技术ID可以,但是您必须记住,对自然关键点仍然保持唯一的约束,并考虑刚才提到的后果

至于燃油价格:您存储的是当前燃油价格,但在订购时没有存储价格。将价格添加到订单表中


关于您的问题:订单和供应商在原始设计中已通过供应商名称链接。在新的设计中,您引入了provider_id。如果您想使用它,请将provider_id放入orders表中。如前所述,您可能希望也可能不希望该表中的提供商名称。

尝试与您的列名保持一致-如果与提供商中的提供商id保持一致,则provider\u fuel中的提供商id会更好。另外,将orders中的provider_name更改为provider_id,并建立了hey presto关系..(使用联接),请注意,“order”在MySQL中是一个保留字,作为表/列标识符是一个糟糕的选择。只需指出,“order”在MySQL中是一个保留字,作为表/列标识符是一个糟糕的选择。非常感谢!为了做出这样的布局,我已经绞尽脑汁两周了。还有一个问题。如何根据供应商产品的价格和订单详细信息中的订单数量显示订单的总值?@草莓-很好,通过将表名更改为客户订单来修复(与采购订单相反,采购订单是授权从其他企业购买商品或服务的文件的标准商业术语)我不喜欢order and provider确实有provider_名称而不是provider_ID,所以我更改了它以简化问题。对于provider and fuel,我想使用技术ID,因为我希望我的fuels,例如,被发现为101、202、303 ID或类似的smth。我只有布局问题,但我在t上收到了答案帽子。现在我在根据订单数量和供应商价格查找订单总值时遇到问题。如上所述,使用技术ID是可以的。我同意它们很容易使用。请记住,您仍然希望供应商表中的供应商名称是唯一的(即,您仍然需要对该列进行约束)出于上述原因,您可能也需要订单表中的名称。我建议您将价格添加到订单表中,因为价格可能会发生变化。您需要对该订单有效的价格,因此请将其存储在那里。获取订单价格很简单:它是订单数量x订单价格。或者您可以只存储订单总价。然后你甚至不用计算,我知道数学