V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
OeO
V2EX  ›  MySQL

请教 sql 数据表设计的问题

  •  
  •   OeO · 2022-10-07 15:09:47 +08:00 · 2444 次点击
    这是一个创建于 814 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题 1

    我有一个数据对象如下需要 mysql 存储: 一个人的基本信息和她可以拥有任意数量的车信息

    const person = {
      name: 'xxx',
      height: 111,
      car: [{
       color: 'xxx',
       price: 111,
      }]
    }
    

    person 对象会按照 SQL 会拆分为两个表,USER 表存放基本信息(name/height) 和 CAR 表存放关联的车辆信息(car),为一对多的关系。

    Q1:如何设计表关系更合理,有两种方式但是不知道那种比较合理?

    USER 的主键做为 CAR 的字段为外键。

    CAR 的主键做为 USER.car 字段的外键。

    现有的设计是 USER 的主键做为 CAR 的外键, 但这样我的 USER 表就会少了一个 CAR 的字段定义。

    Q2: 如何查询出来的结构和我的数据对象一致? 将关联的 CAR 表都查询出来组装为一个数组对象塞到 USER 结果的 car 字段里面。

    问题 2

    我有一个数据对象如下需要 mysql 存储: 一个人的基本信息和她拥有两辆需要对比车辆的信息

    const person = {
      name: 'xxx',
      height: 111,
      car1: {
       color: 'xxx',
       price: 111,
      },
      car2: {
       color: 'xxx',
       price: 111,
      }
    }
    

    person 对象会按照 SQL 会拆分为两个表,USER 表存放基本信息(name/height) 和 CAR 表存放关联的车辆信息(car),为一对一的关系。

    Q: 如果采用将 USER 的主键做为 CAR 的字段为外键,这个查询出来就会有两个结果不知道 car1 ,car2 对应的是那个数据。CAR 的主键做为 USER.car1 ,USER.car1 ,字段的外键又不太符合 sql 的设计。求解这种情况该如何设计表关系了?

    15 条回复    2022-10-09 16:55:38 +08:00
    yhy2008
        1
    yhy2008  
       2022-10-07 15:42:24 +08:00
    问题 1:在 car 表里存 user 的主键比较合理。查询的时候分两次查,先查 user ,再通过 user 主键查 car ,在代码里组装为你需要的对象
    问题 2:在 user 中设置 car1 和 car2 字段,分别存两个 car 对象的主键
    tramm
        2
    tramm  
       2022-10-07 16:12:17 +08:00
    问题一: 人表, 车表, 人车关系表(做好索引). 我们也有个差不多的业务, 一开始也是在车表上有个用户表的 ID, 但是后来有什么 JB 需求, 除了车主之外, 还有第三方用户想看不同部门的多个车辆的信息, 在用户表 /车表固定另一个表的 ID 总是有点局限性的.
    xuanbg
        3
    xuanbg  
       2022-10-07 16:22:08 +08:00
    当然是车表里面有个车主 ID 字段存 uesr_id
    xiangyuecn
        4
    xiangyuecn  
       2022-10-07 17:02:46 +08:00   ❤️ 1
    什么主键 外键的,从来没听过🐶

    设计:设计的再好,难用也白搭,没错:外键难用😂
    kalista
        5
    kalista  
       2022-10-07 18:18:46 +08:00
    才发现我这么些年没用过外键。。。
    OeO
        6
    OeO  
    OP
       2022-10-07 18:26:34 +08:00
    @yhy2008 这么看起来好像只能这么做合理一些。
    @tramm 额,第一次用 sql 开发,感觉还是 nosql(mongodb) 这种存对象方便很多
    @xuanbg 为啥不是用户表里面有一个字段存车表 ID 了,这么做的原因是解耦?
    OeO
        7
    OeO  
    OP
       2022-10-07 18:28:57 +08:00
    @kalista @xiangyuecn 是我太菜还是你们开玩笑😝
    OeO
        8
    OeO  
    OP
       2022-10-07 18:30:50 +08:00
    @kalista 不使用外键,你们对<对象>这种存储咋搞的? nosql ?
    kalista
        9
    kalista  
       2022-10-07 19:43:41 +08:00
    @OeO 我们好像没想那么多,直接引入关联关系就好,就像 3 楼说的车表加一个 user_id, 因为你人跟车是 1:N ,而不是车跟人 1:N ,所以不在用户表加车 ID
    wangritian
        10
    wangritian  
       2022-10-07 20:04:50 +08:00
    2 个问题都是 car 表存 user_id ,外键不用,加好索引即可
    另外表设计不一定严格按照范式,如果业务不需要查询“拥有红色 car 的 user”,可以把 cars 数组直接保存到 user 表的一个 json 字段里
    xuanbg
        11
    xuanbg  
       2022-10-07 20:16:43 +08:00
    @OeO 每辆车只能有一个车主,但每个人只能有一辆车吗?
    OeO
        12
    OeO  
    OP
       2022-10-07 21:33:47 +08:00
    @kalista 我又看了一下文章说的是外键有性能问题,不推荐使用。

    你们不用外键用关联关系是指在车表加一个 user_id 字段起外键的作用但是并非真正的外键,对于使用外键操作用户表会连带操作车表数据的过程,是单独通过程序执行 sql 语句来执行车表的数据操作吗?

    类似于这个等同关系:
    > 关联关系 + 程序执行 sql 操作关联表数据 = 外键
    adoal
        13
    adoal  
       2022-10-07 22:27:39 +08:00
    第一个问题,除了 #1 说的两次查询+业务代码做拼接之外,如果数据库支持的话可以做 array aggregration……
    kalista
        14
    kalista  
       2022-10-08 18:31:38 +08:00
    @OeO 是的,这样做起来最简单
    asmile1993
        15
    asmile1993  
       2022-10-09 16:55:38 +08:00
    可以考虑用 json 数据类型来存储这种数据,比如 json 数组,数组中每个对象是一个 json 对象来存储车辆信息
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2586 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 07:27 · PVG 15:27 · LAX 23:27 · JFK 02:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.