老师,请教下数据库结构设计?

教程中的数据结构设计有用到 decimal 来存储金钱,也用到了外键。
而我所在的公司对数据结构设计有规范:

  1. 时间类字段使用10位时间戳,created_at,updated_at,deleted_at这类的都存bigint型
  2. 必须把字段定义为NOT NULL并且提供默认值
  3. 禁止使用小数存储货币(统一用int存储,精确到分)
  4. 禁止使用ENUM,可使用TINYINT代替
  5. 禁止使用外键,如果有外键完整性约束,需要应用程序控制

还要求了所有删除操作必须使用软删除,因为时间是整型,而且不能为null,默认为0,我们把 SoftDeletesSoftDeletingScope这两个文件都修改了。

看到这里就有很大的困扰,关于上面5个规范要求,在比较正式、商用的项目上,正确、建议的做法应该是怎样的?

我个人对5个规范的想法是:

  1. 时间应该用laravel默认的时间格式,一目了然,用 Carbon 处理其实很方便,而且mysql对date类型已经做了足够优化,占用空间已经不是问题了...吧...
  2. 字段不允许为null 应该是索引性能之类的原因,其实也众说纷纭
  3. 金钱存储应该是decimal 和 int精确到分都可以吧,只是1要团队商量好,2是int型存库和读取时要乘100和除100. 还是想知道哪种更优啊
  4. 不理解,网上也众说纷纭
  5. 不理解,有外键删除的时候可能会报错,不知道是不是这个原因....

求老师解答,鞠躬

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
leo
最佳答案

@aen233 没有大公司的命,得了大公司的病,那能有什么办法……

4年前 评论
讨论数量: 14
leo

不同类型的项目适用的规范不同,如果是 ToC 的可能有高并发场景的项目,确实会通过牺牲开发体验(比如禁止外键、禁止 enum 等)来换取运行效率。

但是我的观点一直是绝大多数项目活不过达到性能瓶颈的那一天,而早一天把项目上线却能多一分成功的可能,对于小公司小项目必须是开发效率第一。

4年前 评论
leo

@aen233 没有大公司的命,得了大公司的病,那能有什么办法……

4年前 评论

第4 使用 ENUM效率没有 TINYINT 效率高 ,但是enum 比较直观
第3 应该是避免小数计算的坑吧 我们之前也都是存储的int 程序中专门定义了一个分元 转化的函数
第1 时间戳为什么使用 bigint 我都是用 int

4年前 评论

@fengzb 为啥用bigint,你可以百度搜下“2038年问题”,因为int整型的取值范围是(-2147483648~2147483647),代表的时间范围是(1901年12月13日20:45:52~2038年1月19日凌晨03:14:07)。我们前端有一个时间插件是从1900年开始的,int根本不满足,测试人员测试极端值,选到2038年之后也会报错。你也不能用unsigned int,因为无符号的是从0开始,表示1970年1月1,如果是存生日,50岁以上的生日就没法存了。。。。

4年前 评论

@aen233 好吧 那我以后也使用 bigint 10 生日就用 date 类型就可以吧

4年前 评论

@aen233 我实例化项目出现一个问题如下 一直执行不下去了
jam@jam-ubuntu-system:/usr/local/nginx/html$ composer create-project --prefer-dist laravel/laravel hxs666
Installing laravel/laravel (v5.8.17)

  • Installing laravel/laravel (v5.8.17): Downloading (connecting...)
    Downloading (100%)
    Created project in hxs666

    @php -r "file_exists('.env') || copy('.env.example', '.env');"
    Loading composer repositories with package information
    Updating dependencies (including require-dev)

4年前 评论

@fengzb 站内文档有一个 Composer 中文镜像,链接是这个 https://learnku.com/laravel/composer

你先按照文档把镜像换了,如果还有问题,再翻翻文档上的常见问题。

反正我每回 composer 不下来,都是镜像或网络的问题。

4年前 评论

@aen233 换了之后 composer 创建项目确实可以了 ; 但是 使用laravel 安装器是不行的 laravel new blog 执行完blog目录下面没有生成 vendor 目录

4年前 评论
leo

不同类型的项目适用的规范不同,如果是 ToC 的可能有高并发场景的项目,确实会通过牺牲开发体验(比如禁止外键、禁止 enum 等)来换取运行效率。

但是我的观点一直是绝大多数项目活不过达到性能瓶颈的那一天,而早一天把项目上线却能多一分成功的可能,对于小公司小项目必须是开发效率第一。

4年前 评论

@fengzb laravel new 要翻墙,你就composer命令创建好了

4年前 评论

@aen233 好的 感谢解惑 :heart: :heart: :heart:

4年前 评论

@leo 就是禁止外键、禁止enum确实能够提升效率的啊.....
可是大部分小公司的开发都默认自己的项目会做的特别大,然后一开始就向已经上了体量的大公司看齐,像大公司一样要求- -
我觉得外键啊、enum、还有timestamp类型的存在一定是有价值啊,它们也一直在更新优化,许多老程序员太坚持惯有的旧模式了(比如时间戳).....

4年前 评论
leo

@aen233 没有大公司的命,得了大公司的病,那能有什么办法……

4年前 评论

@leo 谢谢老师~
把我们想说又不敢说的话说出来了~
可能像老师这样的大佬都已经在大公司需要考虑性能了,
还是希望小公司能多一些像你这样想法的技术总监,少一些“太过于考虑后期维护而在前期设计一堆认为后期有用的东西,但真正到了维护期基本不会觉得当初的设计合理有用”的技术leader

4年前 评论

解释下第二条,NULL 在 Mysql 中是一种特殊值,只能用 IS NULLIS NOT NULL查询,比如一个字段 name 定义为 varchar(10) 允许为 NULL,那么查为空必须是:name = '' OR name IS NULL,如果有很多这些的字段,实际是很蛋疼的。当然 NULL 对索引也有影响

4年前 评论
xiaopi

我以前在一家公司,时间也是存得时间戳,可是这样有问题,mysql有bigint,可是php没有啊,超过2035年得日期,取出来得都是字符型时间戳。。 现在用timestamp存储,也是laravel默认的方式,加上carbon类库,好用的不得了

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!