10

我有一个包含 2 个应用程序(书籍和阅读器)的项目。

Books 应用程序有一个包含 400 万行的表,其中包含以下字段:

 book_title = models.CharField(max_length=40)
 book_description = models.CharField(max_length=400)

为了避免用 400 万行查询数据库,我正在考虑按主题划分它(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。

避免查询具有 400 万行的表是一个很好的解决方案吗?

有替代解决方案吗?

谢谢^__^

4

6 回答 6

15

正如许多人所说,将表拆分为更小的表(水平分区甚至分片)还为时过早。数据库用于处理这种大小的表,因此您的性能问题可能在其他地方。

索引是第一步,听起来你已经做到了。数据库应该可以使用索引处理 400 万行。

其次,检查您正在运行的查询数量。您可以使用 django 调试工具栏之类的工具来执行此操作,并且您经常会惊讶于进行了多少不必要的查询。

缓存是下一步,对大多数用户未更改的页面或部分页面使用 memcached。在这里,您只需付出很少的努力,就能看到最大的性能提升。

如果你真的,真的需要拆分表,最新版本的 django (1.2 alpha) 可以处理分片(例如多数据库),你应该能够手写一个水平分区解决方案(postgres 提供了一个 in-db方法来做到这一点)。请不要使用流派来拆分表格!选择您永远不会改变的东西,并且在进行查询时您将永远知道。像作者一样,除以姓氏的第一个字母或其他东西。对于一个不是特别大的数据库来说,这是一个很大的努力并且有许多缺点——这就是为什么这里的大多数人都反对它!

[编辑]

我省略了非规范化!将常见的计数、总和等放在例如作者表中,以防止常见查询的连接。缺点是您必须自己维护它(直到 django 添加了 DenormalizedField)。我会在开发过程中查看清楚、直接的案例,或者在缓存失败之后——但分片或水平分区之前。

于 2010-01-12T20:20:11.893 回答
11

ForeignKeyIntegerField在数据库中实现的,因此以削弱模型为代价,您几乎没有节省任何费用。

编辑: 为了皮特的缘故,把它放在一张桌子上,并酌情使用索引。

于 2010-01-12T18:50:00.297 回答
1

我对Django不熟悉,但对DB有一个大致的了解。

当您拥有大型数据库时,为您的数据库编制索引是很正常的。这样,检索数据应该很快。

在将书与读者相关联时,您应该创建另一个表,将读者链接到书。

将书籍按主题划分并不是一个坏主意。但我不确定你所说的拥有 20 个应用程序是什么意思。

于 2010-01-12T19:02:51.580 回答
1

你有性能问题吗?如果是这样,您可能需要添加一些索引

了解索引的帮助的一种方法是查看数据库服务器的查询日志(如果您使用的是 MySQL,请点击此处的说明)。

如果你没有性能问题,那就继续吧。数据库可以处理数百万条记录,而 django 非常擅长生成合理的查询。

于 2010-01-12T19:10:05.450 回答
1

此类问题的常见方法是分。不幸的是,实现它主要取决于 ORM(Hibernate 做得很好),而 Django 不支持这一点。但是,我不确定 400 万行是否真的那么糟糕。您的查询应该仍然是完全可管理的。

也许您应该考虑使用memcached 之类的缓存。Django很好地支持了这一点。

于 2010-01-12T19:16:38.063 回答
1

您还没有提到您正在使用哪个数据库。一些数据库——比如 MySQL 和 PostgreSQL——具有非常保守的开箱即用设置,除了微型服务器上的微型数据库之外,这些设置基本上无法用于任何东西。

如果您告诉我们您正在使用哪个数据库,它在什么硬件上运行,以及该硬件是否与其他应用程序共享(例如,它是否也为 Web 应用程序提供服务),那么我们可能会给您一些特定的调整建议。

例如,对于 MySQL,您可能需要调整 InnoDB 设置;对于 PostgreSQL,您需要更改 shared_buffers 和许多其他设置。

于 2012-03-05T11:35:02.337 回答