Tot*_*.js 1 django consistency denormalization
因为我在Django中很新,所以我在这里要求对Django中进行非规范化的最佳实践提出一些建议.按照我的意见,我正在考虑做这样的事情:
我有2个型号:
类别:
name = m.CharField(max_length = 127)
Run Code Online (Sandbox Code Playgroud)
文章:
name = m.CharField(max_length = 127)
category = m.ForeignKey(Category)
category_name = m.CharField(max_length = 127)
Run Code Online (Sandbox Code Playgroud)
我希望这发生:
当我更改任何类别的名称以反映所有文章中的更改时.现在,当我们没有一个或两个字段但大约10-20个字段保持同步时,最佳做法是什么?
谢谢你的帮助 (:
我建议仅在遇到性能问题时才使用关系和非规范化,并且只有在确认此错误性能与查询类别名称相关时才会使用.否则它只是在没有充分理由的情况下增加复杂性.请记住Donald Knuth的名言:
过早优化是万恶之源.
关系数据库擅长连接,因为基本上就是它们的设计目的.在你想要的非规范化设计中,JOINs你需要复杂而不是最简单的设计UPDATEs.这些更新将影响许多(10-20)表中的许多行.如果受影响的表中有大量数据并且经常更改category_name,它甚至会使性能变差.
如果您真的坚持category_name在10-20个表中考虑使用数据库触发器.更改类别表时将执行触发器.它可以在数据库内部处理所有更新.无需更改Django项目中的任何内容,并且开销较小.
因此,如果您真的坚持使用category_name10-20个表中的想法 并且无法使用触发器,那么Django中就会出现一种称为信号的机制.这些是嵌入Django并在定义事件之前/之后触发的触发器.
from django.db.models import signals
from django.core.exceptions import DatabaseError
class Category(m.Model):
def __init__(self, *args, **kwargs):
super(Category, self).__init__(*args, **kwargs)
# Store the initial name
self._name = self.name
name = m.CharField(max_length = 127)
def update_category_name(sender, instance, **kwargs):
""" Callback executed when Category is about to be saved """
old_category = instance._name
new_category = instance.name
if old_category != new_category: # Name changed
# Start a transaction ?
try:
# Update the data:
# Make category_name an db_index, otherwise it will be slooooooooow
Article.objects.filter(category_name=old_category).update(category_name=new_category)
# commit transaction ?
except DatabaseError as e:
# rollback transaction ?
# prevent saving the category as database will be inconsistent
raise e
# Bind the callback to pre_save singal
signals.pre_save.connect(update_category_name, sender=Category)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
827 次 |
| 最近记录: |