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

数据库 model 设计问题

  •  
  •   banks0913 · 2017-01-05 16:33:26 +08:00 · 3497 次点击
    这是一个创建于 2890 天前的主题,其中的信息可能已经有所发展或是发生改变。

    小白请教,业务中需要一个“作品”的 model ,存放类型为纯文本文章、音频、视频三种类型的作品。以下两种设计:

    1. 通用的一个“作品” model ,包含了 content 字段(存放文章内容), attachment 字段(存放视频、音频)。当类型为文章时, attachment 字段为空,当作品类型为视频、音频时, content 字段为空。

    2. 一个抽象的“作品” model ,包含了所有类型作品的通用字段。同时再分别有“文本作品”和“多媒体作品”的 model ,继承于抽象的“作品” model ,分别比“作品”多了 content 字段 和 attachment 字段。

    请教一下,上面两种设计,那种更灵活?

    个人感觉第一种比较灵活,只是字段校验是稍微麻烦点。

    还请各位指点。

    12 条回复    2017-01-05 23:44:11 +08:00
    WildCat
        1
    WildCat  
       2017-01-05 16:45:17 +08:00
    第一种吧, WordPress 貌似就是这么干的
    konakona
        2
    konakona  
       2017-01-05 16:48:39 +08:00
    两种方法都有其各自可取之处,取决于实际业务中,是否有变动来抉择。

    第一种是建立在你肯定这个东西不再多变的基础上。它的好处是节省了查询效率、表空间等。
    第二种适合多变的需求。它的好处是改来改去对其依赖的功能没有影响。

    如果你的老板经常发春,改来改去的,今天附件是 1 个,明天附近是 2 个,后天附件多了个 ext 、 fakename 、 outside_link 之类一堆扩展字段——这种可能性及高,那肯定是用第二种。
    hoythan
        3
    hoythan  
       2017-01-05 16:48:41 +08:00
    ID 自增
    post_author 作者
    post_date 上传时间
    post_date_gmt 上传时间(出现多国家情况下适用)
    post_content 内容
    post_title 标题
    post_status 文章状态
    comment_status 评论状态
    post_password 文章加密
    post_name 文章 url 名称(urlcode 编码)
    post_modified 文章修改时间
    post_modified_gmt
    post_parent 文章上级
    guid 文章 url 地址
    post_type 文章类型
    post_mime_type 文章类型
    comment_count 评论数量




    其中, post_type 包括 post\attachment\page 等
    post_mime_type 包括 image/jpeg 等附件格式或空


    例子:
    当文章 post_type 为 post 或 page 时, post_title 为文章标题, post_comtent 为文章内容,post_mime_type 留空

    当文章 post_type 为 attachment 时, post_title 为文件名称, post_content 为 图片描述, post_mime_type 为附件格式


    格式出自 wordpress
    hoythan
        4
    hoythan  
       2017-01-05 16:52:34 +08:00
    另附一张表, postmeta 用于存放字段相关内容.

    post_meta 包括 meta_id \ post_id \ meta_key \ meta_value

    当 post_type 为 attachment 时,
    meta_key => _wp_attached_file \ meta_value => 服务器绝对路径
    meta_key =>_wp_attachment_metadata \ meta_value => 包括,图片尺寸,大小,版权等信息
    banks0913
        5
    banks0913  
    OP
       2017-01-05 17:02:21 +08:00
    @konakona 有个问题。假设采用第二种方案,如果我需要得到所有作品的点击量排行、热度排行等,不管类型是什么,就需要手动地去取两个 model 的所有内容,合并到一起,并且根据相关排序字段排序后返回 top N 。无法简单地使用 model.objects().order_by()这种操作了,对吧?
    banks0913
        6
    banks0913  
    OP
       2017-01-05 17:36:54 +08:00
    @hoythan meta 表相当于一个 k/v 结构,存放一些不确定的字段?
    cheetah
        7
    cheetah  
       2017-01-05 17:49:30 +08:00
    2
    xxdd
        8
    xxdd  
       2017-01-05 18:00:32 +08:00
    今天 boss 手写代码教会我第二种

    所以我选第二个
    glasslion
        9
    glasslion  
       2017-01-05 18:24:36 +08:00
    @banks0913 第二种; 点击量那些公共信息提取出来放到一个公共的 Model, 各种作品 再外键到那个公共 Model 上; 不要使用 Django 的 Model 继承
    banks0913
        10
    banks0913  
    OP
       2017-01-05 19:19:35 +08:00
    @glasslion 那如果我要对所有类型的作品一起进行查询,或者排序,比如热门作品(不分类别),就需要依次获取几种作品 model 的 objects(),然后合并到一个大的集合里,再对集合进行排序或者之类的操作?
    banks0913
        11
    banks0913  
    OP
       2017-01-05 19:24:06 +08:00
    @glasslion 哦哦,突然反应过来了,对那个公共的 model 操作就好!
    konakona
        12
    konakona  
       2017-01-05 23:44:11 +08:00
    @banks0913 你可以用 ViewModel ( MYSQL 的 View 视图)弄串表。也可以用 ORM 的特性,实现 hasmany 或者 belongs 这种。我推荐 ORM 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6015 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 02:13 · PVG 10:13 · LAX 18:13 · JFK 21:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.