› 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 · Oct 7, 2022 · 3860 views
    This topic created in 1450 days ago, the information mentioned may be changed or developed.

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

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

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

    类似于这个等同关系:
    > 关联关系 + 程序执行 sql 操作关联表数据 = 外键
    adoal
        13
    adoal  
       Oct 7, 2022
    第一个问题,除了 #1 说的两次查询+业务代码做拼接之外,如果数据库支持的话可以做 array aggregration……
    kalista
        14
    kalista  
       Oct 8, 2022
    @OeO 是的,这样做起来最简单
    asmile1993
        15
    asmile1993  
       Oct 9, 2022
    可以考虑用 json 数据类型来存储这种数据,比如 json 数组,数组中每个对象是一个 json 对象来存储车辆信息
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2536 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 04:48 · PVG 12:48 · LAX 21:48 · JFK 00:48
    ♥ Do have faith in what you're doing.