V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
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
fgt1t5y
V2EX  ›  MySQL

数据库存用户头像只存文件名和存完整 URL 哪个好?

  •  
  •   fgt1t5y · 232 天前 · 7797 次点击
    这是一个创建于 232 天前的主题,其中的信息可能已经有所发展或是发生改变。

    哪种好?

    • xxx.jpg
    • /assets/xxx.jpg
    第 1 条附言  ·  231 天前
    谢谢大家的指导,我想了以下还是采用了第一种,只保存文件名。前端请求头像链接时,利用 Laravel ORM 的重写功能为文件名加上目录前缀( xxx.jpg -> /assets/xxx.jpg ),项目在当初设计时要求文件都存在后端服务器上,所以选择这样子。
    59 条回复    2024-05-14 16:36:03 +08:00
    xupefei
        1
    xupefei  
       232 天前 via iPhone
    1
    lianyue
        2
    lianyue  
       232 天前
    尽少我选择
    xxx
    imdong
        3
    imdong  
       232 天前 via iPhone
    文件名以用户相关唯一信息储存,数据库就不用存了,缺点是不会有记录。
    akira
        4
    akira  
       232 天前
    都行,反正不要存文件就行
    fushall
        5
    fushall  
       232 天前
    1 挺好的, 在代码里拼接路径可以灵活一些。
    万一哪天路径要改成 assets/xx/xxx.jpg, assets/yy/yyx.jpg 呢?(这种情况,比如 assets/xx/ 放在了 A 硬盘,assets/yy/ 放在了 B 硬盘
    aru
        6
    aru  
       232 天前
    2
    因为 1 扩展起来挺麻烦的,如果确认只有几万个头像那倒是无所谓
    Casbin
        7
    Casbin  
       232 天前
    @fgt1t5y 存完整 URL ,不差这点存储空间。只存相对路径,一旦需要支持多 URL 基地址(多个 OSS )就 gg 了,具体可以参考 Casdoor: https://github.com/casdoor/casdoor
    hallDrawnel
        8
    hallDrawnel  
       231 天前
    存完整的 URL 。1 限制了前缀只能有一个。
    dcsuibian
        9
    dcsuibian  
       231 天前   ❤️ 2
    看标题我还以为你说的完整 url 是 https://example.com/assets/xxx.jpg 这样呢
    busier
        10
    busier  
       231 天前
    这问题很蛋疼,即使你选了 1 ,以后想改 2 ,只要在 2 变更 path 前,sql 一下批量更新一下就行了。又或者在增加一个字段存放 path 都可以。犯得着这么纠结么,还是不自信?
    facebook47
        11
    facebook47  
       231 天前 via Android
    你这其实都是相对路径,感觉没太大区别🐶,用 2 可能维护容易点,一看就知道在哪里了
    ShinichiYao
        12
    ShinichiYao  
       231 天前
    直接 base64 存数据库,最讨厌大量零碎的小文件
    Lexgni
        13
    Lexgni  
       231 天前
    这俩没区别吧,2 如果有变动也就是再加一层文件夹的事,既然没区别那就选占用少的
    Dragonphy
        14
    Dragonphy  
       231 天前
    为啥不用 OSS 存储图片
    RedBeanIce
        15
    RedBeanIce  
       231 天前
    存文件 id 。
    yinft
        16
    yinft  
       231 天前
    基本成熟点的系统都会直接存 oss 的绝对地址吧
    macaodoll
        17
    macaodoll  
       231 天前 via iPhone
    只要不把二进制直接存进去就都 OK
    wusheng0
        18
    wusheng0  
       231 天前 via Android
    1 吧,路径写在配置文件里面
    Felldeadbird
        19
    Felldeadbird  
       231 天前
    我选第二种,因为我懒。我不想代码在组装一次。
    ladypxy
        20
    ladypxy  
       231 天前
    第一种,只需要保存文件名,文件 URL 可以通过代码拼接
    将来如果要移动到其他目录,代码里修改一下拼接就好了。

    如果用第二种,将来修改路径会很麻烦
    helone
        21
    helone  
       231 天前
    肯定 1 咯,楼上说的多个 OSS 的情况再新增一个 bucket 字段呗,国内这种网络环境,无论是批量更换 CDN 地址或者域名被封都能很快解决
    guanzhangzhang
        22
    guanzhangzhang  
       231 天前
    找找 uid+头像上传时间 生成短链的
    QlanQ
        23
    QlanQ  
       231 天前
    存完整的 URL
    wuxiao2522
        24
    wuxiao2522  
       231 天前
    @ShinichiYao #12 +1
    Tink
        25
    Tink  
       231 天前
    我觉得还是对象存储吧,存 1
    iyiluo
        26
    iyiluo  
       231 天前
    肯定第一种好,数据冗余低,信息密度高,迁移也方便
    kenvix
        27
    kenvix  
       231 天前
    我的做法是写两个字段,filename 和 storage_provider ,这样的做法的好处是只存我文件名就行,并且如果后续需要新的基础路径或者存到 OSS/S3 上,那开个新的 storage_provider id 就行了
    opengps
        28
    opengps  
       231 天前
    存路径,毕竟很有可能将来改成对接对象存储来存储头像,到时候的路径就要改成个网址了
    wuhao1
        29
    wuhao1  
       231 天前   ❤️ 1
    选 1,选 2 这不是我正经历的么?
    老系统:直接 uid.jpg 图片路径都不需要存 如果要调图片(直接饮用传参过来的 id 直接可以得到路径,少查一次数据库,又节省 了数据库的空间
    新系统:有存路径,( oss 的路径,优点:不需要拼装直接从数据库读取地址(也就是上面的 缺点

    我以为第一种更优秀 但是团队协作需要包容更多
    iosyyy
        30
    iosyyy  
       231 天前
    @aru 2 扩展起来不更麻烦 你以后如果要把图片都上到云还都得改 而 1 只需要重写个类改下返回值就能直接用
    julyclyde
        31
    julyclyde  
       231 天前
    @ShinichiYao 为啥要把数据膨胀三分之一存进去呢?
    hhhzccc
        32
    hhhzccc  
       231 天前
    MySQL 存 id 号。OSS 存内容。用的时候作下关联。
    JackLiang
        33
    JackLiang  
       231 天前 via Android
    文件放 oss 省心
    saranz
        34
    saranz  
       231 天前
    这个应该是结合自己的业务需求,如果量级小,那全路径也无所谓。
    但如果业务量大,多一个字符都是浪费。所以连后缀都可以由代码生成。
    ShinichiYao
        35
    ShinichiYao  
       231 天前
    @julyclyde 不是把字符串 base64 ,是把图像文件二进制 base64 存进去
    julyclyde
        36
    julyclyde  
       231 天前
    @ShinichiYao 对啊,你为啥要把图像额外 base64 一步?数据库 blob 字段直接用不就得了?
    RainyH2O
        37
    RainyH2O  
       231 天前
    存储的本质就是选择用什么数据结构当容器存数据罢了,1 就是当作集合,2 就是当作树。实际上不分路径按一定的规范取文件名、给文件分类到不同文件夹、给文件加标签,这些都是当作树存储。选择外部存储也无非是把树结构的信息存到外部罢了。想清楚树结构的信息放到哪最能接受就可以。
    Building
        38
    Building  
       231 天前
    头像不是和 id 或者其他字段关联的吗?不用额外记
    adoal
        39
    adoal  
       231 天前
    头像上传之后按用户 id 编制文件名保存到对象存储。
    mangojiji
        40
    mangojiji  
       231 天前
    这取决于图片是怎样被读取的吧?
    如果图片路径是前端上写死的,那只存名字可以啊。
    如果图片路径是后端下发的,那存完整 URL 或者相对路径都可以。
    panlatent
        41
    panlatent  
       231 天前
    二选一的话,选 1 。概念上区分 “存” 的“原始数据”是文件名而不是 URL ,而“取”(对象方法/属性)的是 URL ,会更好一点。
    ZeekChatCom
        42
    ZeekChatCom  
       231 天前
    存 1 ,占用存储的空间少。
    shuxhan
        43
    shuxhan  
       231 天前
    我们后端选择 2 的做法
    daimaosix
        44
    daimaosix  
       231 天前 via Android
    @shuxhan 给自己找事做是吧
    daimaosix
        45
    daimaosix  
       231 天前 via Android
    @shuxhan 看错了,我以为你是运维😂
    ETiV
        46
    ETiV  
       231 天前 via iPhone
    Web 上一般会有独立的 CDN 域名,这样可以减少请求时携带 Cookies 这些在 CDN 场合没用的东西

    再就是把头像 URL 分成 a)通用的 prefix 部分 & b)不能通用的文件名部份

    prefix 当作程序的常量写在 config 里,文件名部份存数据库里
    mrytsr
        47
    mrytsr  
       231 天前 via Android
    1
    sleepybear1113
        48
    sleepybear1113  
       231 天前
    列 avatar_url (存 xxx.jps ), 列 store_type (如果有不同储存桶)
    zed1018
        49
    zed1018  
       231 天前
    @ShinichiYao #32 难道图片 base64 就不膨胀了吗
    asasjajsajsd
        50
    asasjajsajsd  
       231 天前
    为啥大家和我的都不一样,linux 和 oss 不是有最大文件数限制的么,虽然很大,但不怕这个值直接爆了么,所以很大一部分图片、文件,我都是按日期分文件夹存的,存 2
    panlatent
        51
    panlatent  
       231 天前 via Android
    @asasjajsajsd 并不耽误分子目录
    forty
        52
    forty  
       231 天前
    好不好,看你的痛点在哪。OP 说的这两种,我都不喜欢,我更喜欢直接把图片字节数据存入数据库。
    直接存数据库更灵活,一切都可以动态计算或缓存,也方便防篡改、备份和同步。
    存文件理论上可以减少数据库 IO ,但如果你有 CDN 缓存之类的手段,一样可以实现目的。
    dwu8555
        53
    dwu8555  
       231 天前
    username 就是头像文件名
    quqivo
        54
    quqivo  
       230 天前
    @forty 如果图片太大 存数据库不会影响速度吗
    lisxour
        55
    lisxour  
       230 天前
    从我见过的这么多网站中,80%-90%都是 2 的做法。
    mangojiji
        56
    mangojiji  
       230 天前
    @forty 为什么存文件反而会减少数据库 IO ?
    s4d
        57
    s4d  
       230 天前
    这个肯定是存 Id 了,因为你在不同的地方,要显示同一个图片的不同状态、尺寸之类的。
    forty
        58
    forty  
       230 天前
    @mangojiji 因为文件内容不用从数据库读取了,是读文件系统了。
    forty
        59
    forty  
       230 天前
    > @quqivo "如果图片太大 存数据库不会影响速度吗"

    1. 头像不会太大,上传时就可以给它处理到合适的大小。文件太大,不管存数据库还是文件系统,都影响速度。
    2. 如果图片占流量可观,就得上 CDN 缓解,此时从 OSS 到 CDN 或者从 DB 到 CDN 也基本是一次性的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1451 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 17:09 · PVG 01:09 · LAX 09:09 · JFK 12:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.