V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
VeryZero
V2EX  ›  程序员

请教个问题,为什么数据库的日期用字符串存,字符串格式是 20201027195800 这种

  •  1
     
  •   VeryZero · Oct 27, 2020 · 5006 views
    This topic created in 2011 days ago, the information mentioned may be changed or developed.

    看了好几家公司的 Java 项目都有这么干的,一直想不通。

    数据库是 Oracle,也有 MySQL 的。

    除了这个以外,还有字符串做主键,AA0001 这种。

    还有字符串做关联查询等等。

    最骚的是字符串传参。。

    感觉 Oracle 里的字符串是万能的。是他们太菜了还是我太菜了。。

    36 replies    2020-10-28 17:45:50 +08:00
    wpblank
        1
    wpblank  
       Oct 27, 2020 via iPhone
    我们时间也是上述格式,用 bigint 存。我也不知道为啥。
    jingniao
        2
    jingniao  
       Oct 27, 2020 via Android
    数据库原生 datetime 要注意时区
    int 类型时间戳
    cmdOptionKana
        3
    cmdOptionKana  
       Oct 27, 2020
    日期用字符串很常见,也是有一些好处。
    VeryZero
        4
    VeryZero  
    OP
       Oct 27, 2020
    @wpblank
    @jingniao
    @cmdOptionKana

    你们说的整形存的可能是 unix 时间戳,这个很正常,特别是 PHP 的系统里比较常见,计算比较都很方便。

    但是这是年月日时分秒格式的,比较计算啥的都要用函数。

    不知道好处在哪,所以才问的。

    退一步说就算这种年月日时分秒的格式有某方面的优势,也应该用整形存吧,用字符串真的不用考虑索引的感受吗
    CRVV
        5
    CRVV  
       Oct 27, 2020 via Android   ❤️ 7
    本来就可以这么用,如果你要深究,就保存时间这件事情上,每个方法都会有缺点。

    首先字符串就是任意长度的整数,没什么区别。

    日期时间的存法很多,比如
    1. 用 unix timestamp,缺点是人类不能一眼看出来那是哪天。
    2. 用数据库内置的 datetime 类型,但 MySQL 的 datetime 有奇怪的行为还不能带时区。
    3. 用楼主说的这种,存字符串类型。
    4. 用楼主说的这种,存整数类型。

    4 比 3 省 6 个 byte 的空间。
    但是这个格式一定要从字符串转换过来,用的时候也必然要转回字符串,所以 3 比 4 节省一点 cpu 。

    实际上 3 和 4 的差别是无关紧要的事情,没人在乎 6 个 byte,也没人在乎那一点点 cpu 。
    但 1 和 2 的缺点是确实存在的。
    GopherDaily
        6
    GopherDaily  
       Oct 27, 2020   ❤️ 3
    实话说的话,就是菜
    chendy
        7
    chendy  
       Oct 28, 2020   ❤️ 1
    当处理不好时区还有其他一些奇怪的问题的时候,字符串就是最优解,数字性能更好一些但是也更麻烦一点
    xcstream
        8
    xcstream  
       Oct 28, 2020
    比如查找 10 点到 11 点的数据 , 用 int 存就要每个日期计算一遍。
    chenluo0429
        9
    chenluo0429  
       Oct 28, 2020 via Android   ❤️ 1
    1%的可能是有特殊需求,99%都是因为菜吧
    krixaar
        10
    krixaar  
       Oct 28, 2020
    如果他们存“20201027T195800+0800”也就是再加点无关紧要的佐料是不是就觉得没问题了?毕竟如果确实只在东八区用,+0800 写不写都知道。
    ragnaroks
        11
    ragnaroks  
       Oct 28, 2020
    这说明瓶颈在 web 应用上,不在数据库上
    opengps
        12
    opengps  
       Oct 28, 2020 via Android
    没什么菜不菜的,只是偷懒而已
    xuanbg
        13
    xuanbg  
       Oct 28, 2020   ❤️ 1
    对于接口来说,日期要么字符串传参,要么时间戳传参。还能有别的办法传参?反正我倾向于字符串传参,时间戳还得换算一下才能知道时间,不利于发现问题。
    blless
        14
    blless  
       Oct 28, 2020   ❤️ 1
    写业务多了就会发现时间戳的好处了,尤其是处理一些面向海外的业务
    zsdroid
        15
    zsdroid  
       Oct 28, 2020
    时间戳不可读?加个虚拟列就好了
    wysnylc
        16
    wysnylc  
       Oct 28, 2020
    @GopherDaily #6 +1 就是菜
    时间戳有时区而且索引比字符串要快得多,字符串是索引性能最低的,要不然要那么多整数类型干什么
    wilsonWei
        17
    wilsonWei  
       Oct 28, 2020
    应该用带时区的 timestamp
    qiayue
        18
    qiayue  
    PRO
       Oct 28, 2020
    @wilsonWei 时间戳不分时区的吧
    no1xsyzy
        19
    no1xsyzy  
       Oct 28, 2020
    @xuanbg 有是有,json 的方式传{}或者传[]都可以的。
    比如传 [2020, 10, 27, 19, 58, 00] 还比主题的格式更方便眼 parse
    当然,ISO 8601 也是好的
    只是觉得主题这样毫无 “肉眼解析锚点” 的方式确实不太行。
    不过数据库是另一个问题,有日期格式优先日期格式,没有再看数据量级和需求综合分析,指不定最优方案是同时存储 timestamp 和字符串表示呢。
    GrayXu
        20
    GrayXu  
       Oct 28, 2020
    字符串不是显然解析开销比较大嘛。。
    wilsonWei
        21
    wilsonWei  
       Oct 28, 2020
    @qiayue 也分时区的
    Kr98
        22
    Kr98  
       Oct 28, 2020 via Android
    @wilsonWei timestamp 是以 utc 为基准点,datetime 类型+时区是数据库的功能,和 timestamp 无关。
    wilsonWei
        23
    wilsonWei  
       Oct 28, 2020
    @Kr98 我说的带时区的 timestamp,指的是数据库的字段类型:timestamp with time zone,并非 unix 时间戳
    xuanbg
        24
    xuanbg  
       Oct 28, 2020
    @no1xsyzy ISO 8601 什么的会被前端打死……
    xuanbg
        25
    xuanbg  
       Oct 28, 2020
    @qiayue 时间戳的值没有时区,但获取这个值的时候就和时区有关系了。错误的系统时区将会导致获取到错误的时间戳。
    v2webdev
        26
    v2webdev  
       Oct 28, 2020 via Android
    @CRVV 您好,请教一下,“多出 6 bytes” 是怎么计算的?
    cmdOptionKana
        27
    cmdOptionKana  
       Oct 28, 2020
    @xuanbg 不可能吧,ISO8601 对前端非常友好,js 标准库就支持 ISO8601,最流行的日期时间库 day.js 也重点支持 ISO8601 。
    hitmanx
        28
    hitmanx  
       Oct 28, 2020
    @v2webdev 我猜他指的是 char[14] vs uint64_t
    a719031256
        29
    a719031256  
       Oct 28, 2020
    太懒了
    我手上的项目就遇到,给建表的人说字段属性跟注释有歧义,然后这家伙就直接把所有字段属性改为 varchar,所有的值含义都通过口口相传
    wilsonWei
        30
    wilsonWei  
       Oct 28, 2020
    @a719031256 好家伙。。这规范也太差劲了,没人管管吗。。。
    a719031256
        31
    a719031256  
       Oct 28, 2020
    @wilsonWei 管什么,国企的开发只要文档够标准就行了,至于代码和数据库设计将就效率而不是质量,文档要求每一个功能点要够详细,截图要多。。。。
    CRVV
        32
    CRVV  
       Oct 28, 2020   ❤️ 1
    @v2webdev
    用整数的话,32 位不够,那就要用 64 位的,占 8 bytes
    那个字符串是 14 个数字,14 bytes

    如果用定长的字符串,也就是不需要额外存长度,也不需要在结尾补一个 0,那就是差 6 bytes
    ETiV
        33
    ETiV  
       Oct 28, 2020 via iPhone
    存时间戳
    海外不仅跨时区,遇到有夏令时的地方有的搞了…
    wilsonWei
        34
    wilsonWei  
       Oct 28, 2020
    @a719031256 好吧,追求不一样
    a719031256
        35
    a719031256  
       Oct 28, 2020
    @wilsonWei 这些人就是懒,啥事都是扔给我们帮他们弄,还有另一个人脸识别项目,海康 sdk 部署 Linux 环境居然不知道把动态库扔到系统库中,还要让我周六帮他弄,明明海康的文档写得清清楚楚
    wilsonWei
        36
    wilsonWei  
       Oct 28, 2020
    @a719031256 这些大爷们就是懒,工作一点都不上心
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   811 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 103ms · UTC 21:46 · PVG 05:46 · LAX 14:46 · JFK 17:46
    ♥ Do have faith in what you're doing.