【问题标题】:relational model query for simple person-car example简单人车示例的关系模型查询
【发布时间】:2020-06-04 01:23:22
【问题描述】:

我想了解一下我为 PostgreSQL 创建的关系模型。它与人和汽车的关系有关。

CREATE TABLE "person" (
"id" serial NOT NULL PRIMARY KEY,
"name" varchar(300) NOT NULL,
"car_id" integer REFERENCES car (id));

CREATE TABLE "car" (
"id" serial NOT NULL PRIMARY KEY,
"type" varchar(50) NOT NULL);

 CREATE TABLE "car_person_relations" (
"id" serial NOT NULL PRIMARY KEY,
"car_type" varchar(50) NOT NULL REFERENCES "car" ("type"),
"person_id" integer NOT NULL REFERENCES "person" ("id"));

最终,我想根据拥有的人数获得最受欢迎的车型, 即它与多少个“人”相关联。我可以使用什么查询来实现这一点?这个关系表(car_person_relations)是否足以实现它?

任何见解将不胜感激

【问题讨论】:

  • 请展示您的尝试。你能做哪些部分?但这是一个常见问题解答。在考虑发布之前,请阅读您的教科书和/或手册和谷歌任何错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有和没有您的特定字符串/名称和站点:stackoverflow.com 和标签;阅读许多答案。如果您发布问题,请使用一个短语作为标题。反映你的研究。请参阅How to Ask 和投票箭头鼠标悬停文本。
  • 谢谢菲尔。如果我的问题与 StackOverflow 的“如何提问”政策不一致,我深表歉意。坦率地说,我对数据库完全陌生,我只是不知道从哪里开始或从哪里开始,但我一定会在以后的问题中记住这一点。 @philipxy
  • 这能回答你的问题吗? mySQL query to find the most repeated value

标签: sql database postgresql database-design


【解决方案1】:

如果我理解正确,这是一个有一些限制的简单聚合:

select car_type, count(*) as num_persons
from car_person_relations cpr
group by car_type
order by count(*) desc
limit 1;

【讨论】:

    【解决方案2】:

    首先看一下您的数据模型,它有几个基本问​​题。 在 CAR_PERSONS_RELATIONS 表中,您尝试在 car_type 上创建 FK。但是,这样做 car_type 必须是 在汽车表中独一无二。来自文档部分 5.4.5. Foreign Keys

    外键约束指定列(或一组列)中的值必须与值匹配 出现在另一个表的某行。我们说这保持了 两个相关表之间的参照完整性。 ... 外键 必须引用作为主键或形成唯一键的列 约束。

    但是这样的话,给定类型的汽车只能有 1 辆 桌子。

    现在查看 PERSON 表。该表包含一个到 car_id 的 FK,因此建立了一个到 CAR 的 M:1。基本上这种关系 说“一个人只能拥有一辆车,但一辆车可以被很多人拥有”。您的描述和表名表明 这不是您要定义的关系。

    更正需要进行以下更改:

    1. 将 car_id 添加到 CAR_PERSON_RELATIONS。
    2. 从 PERSON 中删除 car_id。
    3. 从 CAR_PERSON_RELATIONS 中删除 car_type。
    4. 将 CAR_PERSON_RELATIONS PK 重新定义为 car_id、person_id。
      交替 离开代理 PK 并在 car_id,person_id 上创建 UK)。
    5. 创建从 CAR_PERSON_RELATIONS 到 CAR 和 PERSON 的 FK。

    修正模型

    create table person (
       id   serial       
      ,name varchar(300) not null
      ,constraint person_pk primary key (id) 
    );
    
    create table car (
       id serial  
      ,type varchar(50) not null
      ,constraint car_pk primary key (id)  
      );
    
    create table car_person_relations (
       car_id    integer   
      ,person_id integer 
      ,constraint car_person_relations primary key (car_id, person_id)
      ,constraint car_person_relations_2_car_fk
                  foreign key (car_id) 
                  references  (car.id)
      ,constraint car_person_relations_2_person_fk
                  foreign key (person_id) 
                  references  (person.id)
    ): 
    

    然后必要的查询变成:

    select cpr.car_type, count(*) as num_persons
      from car_person_relations cpr
      join car                  c
        on cpr.car_id = c.id 
     group by cpr.car_type
     order by count(*) desc
     limit 1;
    

    【讨论】:

      猜你喜欢
      • 2014-10-10
      • 1970-01-01
      • 2017-03-11
      • 2013-07-15
      • 2018-08-24
      • 2014-01-18
      • 2022-01-26
      • 2011-06-08
      相关资源
      最近更新 更多