Oracle/mySQL 数据库

Oracle/mySQL database

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

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 的提供者和燃料创建一个 ALTER TABLE 来解决多对多关系,但我没有我不知道如何在订单和供应商之间建立联系。

我已经像这样更改了实体:

provider(PROVIDER_ID, PROVIDER_ADRESS);
fuel(FUEL_CODE, FUEL_NAME);
provider_fuel(ID_ENTRY, ID_PROVIDER, ID_FUEL, PRICE, STOCK).

这样还可以吗?如果是这样,我如何在我的数据库中的所有这些实体之间建立连接?

我不得不提一下,我的应用程序应该允许客户从具有特定燃料、价格等的供应商处下订单。

您可以按顺序 id_provider table 并通过 id 获取提供商详细信息。例如

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

欢迎来到 Oracle 数据库世界!

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

在您的示例中,您可以像这样连接表格:

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

但在联接中使用 NUMBER 类型的列总是更好。所以我建议,在 2 个表上创建 provider_id(NUMBER 类型)并加入它们。

SQL 中有 5 种主要的联接类型(INNER、OUTER、FULL、LEFT、RIGHT)。他们每个人都提供不同的东西。

我会建议以下 table 布局:

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);

如果你愿意,你可以展开这个。例如,供应商可能有多个供应产品的地点,在这种情况下,您需要将单个供应商 table 重新工作为

PROVIDER(ID_PROVIDER, NAME)

PROVIDER_PRODUCT(ID_PROVIDER, ID_PRODUCT, PRICE)

PROVIDER_ADDRESS(ID_PROVIDER_ADDRESS, ID_PROVIDER, ID_ADDRESS)

然后将 PROVIDER_PRODUCT 重做为

PROVIDER_ADDRESS_PRODUCT(ID_PROVIDER_ADDRESS, ID_PRODUCT, STOCK_QTY)

我想供应商收取的价格也可能取决于发货地点,因此您可能需要更改型号以适应这一点。关键是有很多不同的方法可以做到这一点,这在很大程度上取决于您的要求。

编辑

要使用上面的 tables 获取订单的总价值,您将使用如下查询:

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

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

  • 客户有一些登录代码可以识别他们 (client_code)。
  • 提供者由其名称标识。你想要这个吗?这意味着提供商地址保持不变且无法更改。这可能需要也可能不需要。如果公司 JACOB'S FUELSHOP INC 更改为 THE FUELSHOP INC,您要将其视为同一公司还是不同公司?
  • 您还可以生成订单号。您希望它们在您的数据库中是唯一的,还是每个客户或每个提供商?订单 table 的键相应地只是 order_number 或 order_number + client_code 或 order_number + provider_name.

现在您不希望一家供应商只销售一种燃料,而是销售多种燃料。你介绍一座桥table。但在同一步骤中,您将引入技术 ID。您想使用技术 ID 而不是自然键吗?

您有 provider(PROVIDER_ID, PROVIDER_ADRESS),但地址中缺少或包含提供者的名称。这允许您稍后更改名称。但请记住,您可能希望在每次订单时都存储名称,因为您可能希望稍后重新打印它,或者只是说明您是通过合法公司 JACOB'S FUELSHOP INC 还是 THE FUELSHOP INC 下订单的。技术 ID 很好,但您必须记住仍然对自然键保持唯一约束,并像刚才提到的那样考虑后果。

关于燃油价格:您存储的是当前燃油价格,但您没有存储订购时的价格。将价格添加到订单 table.

关于您的问题:Order 和 provider 在最初的设计中已经通过 provider_name 链接。在新设计中,您引入了 provider_id。如果您想改用它,请将 provider_id 放在命令 table 中。如前所述,您可能也可能不想要 table 中的提供商名称。