请教 sql 数据表设计的问题

2022-10-07 15:09:47 +08:00
 OeO

问题 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 的设计。求解这种情况该如何设计表关系了?

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

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

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

类似于这个等同关系:
> 关联关系 + 程序执行 sql 操作关联表数据 = 外键
adoal
2022-10-07 22:27:39 +08:00
第一个问题,除了 #1 说的两次查询+业务代码做拼接之外,如果数据库支持的话可以做 array aggregration……
kalista
2022-10-08 18:31:38 +08:00
@OeO 是的,这样做起来最简单
asmile1993
2022-10-09 16:55:38 +08:00
可以考虑用 json 数据类型来存储这种数据,比如 json 数组,数组中每个对象是一个 json 对象来存储车辆信息

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/885022

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX