V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
SimbaPeng
V2EX  ›  程序员

字段尽量设置为 not null 是 Mysql 特有的惯例吗?其他的数据库(例如 Postgres)需要这样做吗?

  •  
  •   SimbaPeng · 2018-05-04 13:16:15 +08:00 · 4266 次点击
    这是一个创建于 2394 天前的主题,其中的信息可能已经有所发展或是发生改变。
    28 条回复    2018-05-05 01:08:26 +08:00
    MeteorCat
        1
    MeteorCat  
       2018-05-04 13:20:43 +08:00
    默认 null 占据一个数据一个字节,每条数据多分配一个字节的空间来表示字段是否为空,无论你是否使用到 null
    MeteorCat
        2
    MeteorCat  
       2018-05-04 13:27:33 +08:00
    Postgres 没接触过,mysql 和 mariadb 就是这样,不排除其他数据库软件有所优化
    SimbaPeng
        3
    SimbaPeng  
    OP
       2018-05-04 13:31:32 +08:00
    @MeteorCat 设置了 not null 的话,像 datetime 这种数据类型如何给默认值?
    sagaxu
        4
    sagaxu  
       2018-05-04 13:35:45 +08:00 via Android
    比如说温度,你用什么值表示这项数据无效?不用 null 再加个字段吗?
    congeec
        5
    congeec  
       2018-05-04 13:37:11 +08:00 via iPhone
    @sagaxu -1 kelvin degree
    MeteorCat
        6
    MeteorCat  
       2018-05-04 13:38:11 +08:00
    @SimbaPeng
    如果需要不留空,比如 create_datetime 这种创建就需要生成的,就直接当时的时间默认值
    如果需要留空,那么比如 update_datetime 这种实时更新,但是前期不留空的,直接给他一个会被识别为 null 字符串 `"0000-00-00 00:00:00"`;如果取出来的话,需要判断是不是该格式,我一般都是时间戳保存转换
    shansing
        7
    shansing  
       2018-05-04 13:39:24 +08:00
    @congeec 0 度就行了 :doge:
    niubee1
        8
    niubee1  
       2018-05-04 13:39:27 +08:00
    比如你定义一个字段是 boolean 类型, 但是如果不是 not null 的话, 而你又忘记给这个字段赋值, 那么, 这个字段就会有 null, false, true 三个状态
    MeteorCat
        9
    MeteorCat  
       2018-05-04 13:39:45 +08:00
    @sagaxu 这种情况也是需要考虑,建议楼主也纳入这种考虑
    MeteorCat
        10
    MeteorCat  
       2018-05-04 13:40:49 +08:00
    @shansing 不行,现实上测试过,0 在温度面前也是个特殊值,因为有的地方温度也是存在 0 度,不能将具体存在的温度纳入错误之中
    PressOne
        11
    PressOne  
       2018-05-04 13:41:45 +08:00 via Android
    新版 MySQL 早就没有这个必要了,按需设置,没有数据就 Null,不用强求,不影响索引效率。
    sagaxu
        12
    sagaxu  
       2018-05-04 13:42:17 +08:00 via Android
    @congeec 然后用求和或者平均等函数做聚集的时候再 where 筛一下先?
    congeec
        13
    congeec  
       2018-05-04 13:43:34 +08:00 via iPhone
    @niubee1 这种情况用 0,1,2 表示更省空间。而且适合用 bitmap 索引
    congeec
        14
    congeec  
       2018-05-04 13:46:22 +08:00 via iPhone
    @sagaxu 嗯啊,你说的对。可能一不小心就写错了。性能倒不是问题
    alvinbone88
        15
    alvinbone88  
       2018-05-04 14:54:44 +08:00   ❤️ 4
    MySQL 里字段尽量不要为空主要是为了排序的考虑,而不是索引的考虑
    在 MySQL 里,null 值永远是最小的,而且 null 与其他任何值比较的结果都是 false
    这就导致用 ASC 排序时 null 值永远在最前面
    lihongjie0209
        16
    lihongjie0209  
       2018-05-04 15:07:13 +08:00
    @MeteorCat #10 -99999 考虑一下, 之前看到有人用 unix time 的开始时间作为时间的默认值或者是异常值
    jjx
        17
    jjx  
       2018-05-04 16:44:06 +08:00
    最好取默认值, 否则实际操作中很麻烦

    比方说 pg, 要取空白的记录需要

    select * from sale_orders where source is null or source='';
    MeteorCat
        18
    MeteorCat  
       2018-05-04 17:30:25 +08:00
    @lihongjie0209 这种代码层面的验证移交给数据库本身就是极其错误的,数据库不对数据准确性负责,只负责你有数据 insert 没有错误就行了
    MeteorCat
        19
    MeteorCat  
       2018-05-04 17:45:54 +08:00
    @lihongjie0209 对了,这种还涉及数据库字段的正确配置,比如你 datetime|tinyint 强制硬塞给一个"123456789"|9999----->"0000-00-00 00:00:00"|255,这种我感觉有点离题但是却是个值得思考的问题,因为一方面制定数据库得考虑这些,一方面还要在 DAO 层做这样的判断
    niubee1
        20
    niubee1  
       2018-05-04 18:42:31 +08:00
    @congeec 我说的这是一个问题而不是一个特性啊, 你没 get 到点
    eslizn
        21
    eslizn  
       2018-05-04 18:47:04 +08:00
    看场景来的,楼上各种说默认值的,可能没遇到某个字段唯一,但是是可选的情况
    glues
        22
    glues  
       2018-05-04 18:55:17 +08:00 via iPhone
    能加默认值的就尽量 not null,不能加的就不强求
    shansing
        23
    shansing  
       2018-05-04 19:59:01 +08:00
    @MeteorCat 不是,我是接那层楼的玩笑,说开尔文温度。绝对零度在现实世界是不会有的。
    AltairT
        24
    AltairT  
       2018-05-04 20:18:47 +08:00
    @MeteorCat 这个应该是类似单片机里那个思路,就是把-500~2000 映射到 0~25000 (包括一位小数),就是需要转换一下罢了。不知其他胖友有更好思路吗?
    MeteorCat
        25
    MeteorCat  
       2018-05-04 20:19:44 +08:00 via Android   ❤️ 1
    @shansing 哈哈哈,不过确实冬季有零度产生的,这个其实是想说 PHP 这种语言很多人都会直接拿 null 和 0 等同 if(null==0),导致有时候到底是哪个字段本身是 null 还是本身温度就是 0,这种假设是存在的
    MeteorCat
        26
    MeteorCat  
       2018-05-04 20:23:19 +08:00 via Android
    @AltairT 这种-和+的数组情况我们都是有判断极限值的,这种我记得以前 c 的 strlen 以前也有缓冲区溢出攻击,所以基本上都是有做极限值判断
    lolizeppelin
        27
    lolizeppelin  
       2018-05-04 20:48:21 +08:00 via Android
    @MeteorCat

    绝对 0 为起始值啊
    MeteorCat
        28
    MeteorCat  
       2018-05-05 01:08:26 +08:00
    @lolizeppelin = =我以爲是普通零度
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5320 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 07:12 · PVG 15:12 · LAX 23:12 · JFK 02:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.