V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
746970179
V2EX  ›  Python

django 求教数据库设计, 是否需要进行大表拆小表

  •  
  •   746970179 · 2017-04-05 11:05:50 +08:00 · 3075 次点击
    这是一个创建于 2790 天前的主题,其中的信息可能已经有所发展或是发生改变。

    基础介绍:

    1. 主表 package 每天新增的数据量可能达到 10w 条, 预计生命周期 3 年吧(1 亿条), 不准备水平拆分
    2. 有一个 condition 表, package 根据基础信息, 在 condition 表中找到合适的 condition, 保存其外键, 留作后续统计使用
    3. django 项目

    主要问题: package 的基础信息, 有 3 组: 预估信息, 校验信息, 最终信息, 三组结构基本一致 如果保存 condition 的外键, 根据三组信息, 会保存三套外键

    在考虑是否需要使用 django 的 OneToOneField 进行 package 表的拆分 将大表拆分成 两张 或 三张 小表

    优越的地方是 结构清晰, 主表大小降低了 但不确定的是:

    1. 是否有拆分的必要
    2. 使用 OneToOneField, 是不是一个相对比较标准的方式
    3. 除了删除不同步(但是业务并不需要删除), OneToOne 字段是否有其他问题

    谢谢!

    5 条回复    2017-04-06 14:49:29 +08:00
    guolingbing
        1
    guolingbing  
       2017-04-05 19:40:16 +08:00 via Android   ❤️ 1
    我觉得没这个必要,如果列很多,直接指定要返回的字段就好,不过实在要拆用 OneToOneField 是挺好的,删除的问题指定好 on_delete 就行了,我记默认就是 cascade
    ytmsdy
        2
    ytmsdy  
       2017-04-05 21:41:56 +08:00   ❤️ 1
    1 :关于是否需要拆分,需要确认的是, django 在做数据查询时, ORM 是否会把所有数据都带出来(也就是 Select * 和 Selece 特定字段的区别)。还有一个情况就是字段的存储的大小,如果都是小字段,其实没有太大的拆分必要。如果存储的字段都是大字段,我觉得还是有拆分的必要的。
    2 :建议还是用 OneToOne 的方式吧,这样可以保持一个数据库结构的完整性
    3 :其他问题,暂时未知。

    ps :如果 LZ 不准备做水平拆分,目前只考虑垂直拆分。只需要从存储的字段大小以及 ORM 的性能上来考虑。如有不正确的地方,请斧正。
    746970179
        3
    746970179  
    OP
       2017-04-05 22:38:46 +08:00
    @guolingbing @ytmsdy
    感谢回复, 主要是至少三组数据, 每组数据有 4~5 个字段, 其中有 1~2 个是外键
    如果全部存一张表, 那么担心
    1. 外键太多, 一张表有十几个, 担心不太好. 个人对数据库设计, 并没有太深刻的理解, 只是喜欢一般一张表 20 个字段左右, 这样理解, 记忆什么的比较方便
    2 未来如果进行业务扩展, 因为只有一张表, 那么担心这张表会过大(目前 3 组, 全部 30 个字段左右了, 扩展 2 组数据, 会有四十多个字段, 感觉表很冗余了)
    最终, 选择的方案是拆分成两张表, 原则是根据业务的主次进行拆分, 主要业务放主表, 然后将辅助性的数据(相对不常用)全部放到扩展表中, 后续如果进行扩展, 也按照这个原则, 将字段添加到对应的表中.
    没有根据数据逻辑, 因为根据数据逻辑, 拆分的不止两张表, 那样有点太多, 所以折中使用业务逻辑拆分.

    @ytmsdy 想做水平拆分, 但是使用 django+mysql 不太会, 后面准备使用的方案是进行数据归档, 当数据量增长到一定程度, 将历史数据从原表中 copy 到另一张表(或者数据库), 再从原表中删除(以当前的技术水平, 这个方案可行性最高了,,,,,,,见笑了)
    @ytmsdy orm 默认不会带出所有的外键对象的数据, 如果需要, 指定 select_related('foreignkey')即可, 相对来说, django orm 是真的强大+易用的
    georgema1982
        4
    georgema1982  
       2017-04-06 04:22:52 +08:00   ❤️ 1
    像你这种情况,不应该通过 onetotone 拆成多张表,因为你的 package 表的数据太多,一旦主表通过外建来 join 子表,开销非常大。按照你的情况,你应该就保持一张 package 表,然后通过 proxy model ( https://docs.djangoproject.com/en/1.10/topics/db/models/#proxy-models )来定义几种子类
    746970179
        5
    746970179  
    OP
       2017-04-06 14:49:29 +08:00
    @georgema1982 十分感谢(还很细心的提供了文档链接)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5358 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 01:30 · PVG 09:30 · LAX 17:30 · JFK 20:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.