我有一个包含2个应用程序(书籍和阅读器)的项目.
Books应用程序有一个包含4百万行的表,其中包含以下字段:
book_title = models.CharField(max_length=40) book_description = models.CharField(max_length=400)
为了避免用4百万行查询数据库,我想按主题划分它(20个模型,20个表,200,000行(book_horror,book_drammatic,ecc).
在"阅读器"应用程序中,我想插入这些字段:
reader_name = models.CharField(max_length=20, blank=True) book_subject = models.IntegerField() book_id = models.IntegerField()
因此,我想使用整数"book_subject"(允许访问相应的表)和"book_id"(允许访问"book_subject"中指定的表中的书),而不是ForeignKey.
是一个很好的解决方案,以避免查询具有4百万行的表?
有替代解决方案吗?
谢谢^ __ ^
像许多人所说的那样,将表分成较小的表(水平分区甚至分片)还为时过早.数据库用于处理此大小的表,因此您的性能问题可能在其他地方.
索引是第一步,听起来你已经这样做了.数据库可以使用索引处理400万行.
其次,检查您正在运行的查询数.您可以使用django调试工具栏之类的东西来执行此操作,并且您经常会惊讶地发现了多少不必要的查询.
缓存是下一步,对于大多数用户未更改的页面或页面部分使用memcached.在这里,您将看到您所需的最小努力所带来的最大性能提升.
如果你真的,真的需要拆分表,最新版本的django(1.2 alpha)可以处理分片(例如multi-db),你应该能够手写一个水平分区解决方案(postgres提供in-db这样做的方法).请不要使用流派来分割表格!选择一些你永远不会改变的东西,并且你在查询时总会知道.像作者一样,除以姓氏的第一个字母或其他东西.这是一项很大的努力,并且对于数据库来说有很多缺点,这个数据并不是特别大 - 这就是为什么这里的大多数人都在反对它的建议!
[编辑]
我遗漏了非规范化!在例如作者表中放置常用计数,总和等,以防止对常见查询进行连接.缺点是你必须自己维护它(直到django添加一个DenormalizedField).我想看看这个发展过程中明确,直接的情况下或在缓存失败你---但也分片或水平分区之前.
ForeignKey
被实现为IntegerField
在数据库中,所以你很少保存到一无所有削弱模型的成本.
编辑: 为了皮特的缘故,将它保存在一个表中并根据需要使用索引.