当前位置: 首页 > news >正文

数据库完整指南:从基础到 Django 集成

目录

  1. 数据库基础概念

  2. 关系型数据库

  3. Django 数据库配置

  4. Django 模型详解

  5. 数据库迁移

  6. 数据库查询

  7. 数据库关系

  8. 数据库优化

  9. 生产环境部署

数据库基础概念

什么是数据库?

数据库是结构化信息的集合,用于高效存储、管理和检索数据。

数据库类型

  • 关系型数据库:MySQL、PostgreSQL、SQLite

  • 非关系型数据库:MongoDB、Redis

  • 时序数据库:InfluxDB

  • 图数据库:Neo4j

ACID 原则

  • 原子性:事务要么全部完成,要么全部不完成

  • 一致性:事务必须使数据库从一种一致状态变为另一种一致状态

  • 隔离性:并发事务之间互不干扰

  • 持久性:事务完成后,对数据库的修改是永久的

关系型数据库

核心概念

sql

-- 数据库操作
CREATE DATABASE mydb;
USE mydb;-- 表操作
CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) UNIQUE NOT NULL,email VARCHAR(100) NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);-- 数据操作
INSERT INTO users (username, email) VALUES ('john', 'john@example.com');
SELECT * FROM users WHERE username = 'john';
UPDATE users SET email = 'new@example.com' WHERE id = 1;
DELETE FROM users WHERE id = 1;

常见关系型数据库比较

数据库特点适用场景
MySQL流行、成熟、社区强大Web应用、中小型系统
PostgreSQL功能丰富、标准兼容性好复杂应用、地理数据
SQLite轻量级、零配置移动应用、小型项目
Oracle企业级、功能强大大型企业系统

Django 数据库配置

基本配置

python

# settings.py
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': BASE_DIR / 'db.sqlite3',}
}

PostgreSQL 配置

python

# settings.py
DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql','NAME': 'mydatabase','USER': 'mydatabaseuser','PASSWORD': 'mypassword','HOST': 'localhost','PORT': '5432','CONN_MAX_AGE': 600,  # 连接存活时间(秒)'OPTIONS': {'connect_timeout': 10,}}
}

MySQL 配置

python

# settings.py
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'mydatabase','USER': 'mydatabaseuser','PASSWORD': 'mypassword','HOST': 'localhost','PORT': '3306','OPTIONS': {'charset': 'utf8mb4','init_command': "SET sql_mode='STRICT_TRANS_TABLES'",},'TEST': {'CHARSET': 'utf8mb4','COLLATION': 'utf8mb4_unicode_ci',}}
}

多数据库配置

python

# settings.py
DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql','NAME': 'primary_db',# ... 其他配置},'read_replica': {'ENGINE': 'django.db.backends.postgresql','NAME': 'replica_db',# ... 其他配置},'logging': {'ENGINE': 'django.db.backends.sqlite3','NAME': BASE_DIR / 'logs.db',}
}# 数据库路由
DATABASE_ROUTERS = ['myapp.routers.DatabaseRouter']

Django 模型详解

基础模型定义

python

# models.py
from django.db import models
from django.urls import reverse
from django.core.validators import MinLengthValidator, MaxValueValidatorclass TimestampModel(models.Model):"""抽象基类,提供时间戳字段"""created_at = models.DateTimeField(auto_now_add=True)updated_at = models.DateTimeField(auto_now=True)class Meta:abstract = Trueclass User(TimestampModel):# 字段类型username = models.CharField(max_length=50,unique=True,validators=[MinLengthValidator(3)],verbose_name='用户名')email = models.EmailField(unique=True, verbose_name='邮箱')age = models.PositiveIntegerField(null=True,blank=True,validators=[MaxValueValidator(150)],verbose_name='年龄')is_active = models.BooleanField(default=True, verbose_name='是否激活')birth_date = models.DateField(null=True, blank=True, verbose_name='出生日期')salary = models.DecimalField(max_digits=10,decimal_places=2,null=True,blank=True,verbose_name='薪资')bio = models.TextField(blank=True, verbose_name='个人简介')avatar = models.ImageField(upload_to='avatars/',null=True,blank=True,verbose_name='头像')# 元数据class Meta:verbose_name = '用户'verbose_name_plural = '用户'ordering = ['-created_at']indexes = [models.Index(fields=['username']),models.Index(fields=['email', 'is_active']),]constraints = [models.CheckConstraint(check=models.Q(age__gte=0),name='age_positive')]def __str__(self):return self.usernamedef get_absolute_url(self):return reverse('user_detail', kwargs={'pk': self.pk})@propertydef display_name(self):return f"{self.username} ({self.email})"def save(self, *args, **kwargs):# 保存前的自定义逻辑self.email = self.email.lower()super().save(*args, **kwargs)

字段类型详解

字段类型说明对应数据库类型
CharField字符串字段VARCHAR
TextField大文本字段TEXT
IntegerField整数字段INTEGER
DecimalField十进制数字段NUMERIC
BooleanField布尔字段BOOLEAN
DateTimeField日期时间字段DATETIME
DateField日期字段DATE
TimeField时间字段TIME
EmailField邮箱字段VARCHAR
URLFieldURL字段VARCHAR
FileField文件字段VARCHAR
ImageField图片字段VARCHAR

字段选项

python

class ExampleModel(models.Model):# 常用字段选项name = models.CharField(max_length=100,null=True,           # 数据库允许NULLblank=True,          # 表单验证允许空值default='Unknown',   # 默认值unique=True,         # 唯一值db_index=True,       # 创建索引choices=[            # 选择项('draft', '草稿'),('published', '已发布'),],help_text='请输入名称',  # 帮助文本verbose_name='名称'     # 可读名称)

数据库迁移

迁移命令

bash

# 创建迁移文件
python manage.py makemigrations# 查看迁移SQL
python manage.py sqlmigrate myapp 0001# 应用迁移
python manage.py migrate# 查看迁移状态
python manage.py showmigrations# 撤销迁移
python manage.py migrate myapp 0001# 数据迁移
python manage.py makemigrations --empty myapp

自定义迁移

python

# myapp/migrations/0002_custom_migration.py
from django.db import migrations, modelsdef add_default_categories(apps, schema_editor):Category = apps.get_model('myapp', 'Category')Category.objects.bulk_create([Category(name='技术'),Category(name='生活'),Category(name='旅游'),])def remove_default_categories(apps, schema_editor):Category = apps.get_model('myapp', 'Category')Category.objects.filter(name__in=['技术', '生活', '旅游']).delete()class Migration(migrations.Migration):dependencies = [('myapp', '0001_initial'),]operations = [migrations.RunPython(add_default_categories,remove_default_categories),]

数据库查询

基础查询

python

from myapp.models import User, Post
from django.db.models import Q, Count, Avg, Sum# 创建
user = User.objects.create(username='john', email='john@example.com')# 查询所有
users = User.objects.all()# 过滤查询
active_users = User.objects.filter(is_active=True)
john_users = User.objects.filter(username__contains='john')
recent_users = User.objects.filter(created_at__gte='2024-01-01')# 排除查询
inactive_users = User.objects.exclude(is_active=True)# 获取单个对象
try:user = User.objects.get(id=1)
except User.DoesNotExist:user = None# 快捷方法
user = User.objects.filter(id=1).first()# 复杂查询
complex_query = User.objects.filter(Q(is_active=True) & (Q(username__startswith='j') | Q(email__contains='example'))
)# 排序
users_ordered = User.objects.order_by('-created_at', 'username')# 切片
recent_10_users = User.objects.order_by('-created_at')[:10]

高级查询方法

python

# 聚合查询
from django.db.models import Count, Avg, Max, Minstats = User.objects.aggregate(total_users=Count('id'),avg_age=Avg('age'),max_salary=Max('salary')
)# 分组查询
user_posts_count = User.objects.annotate(post_count=Count('posts')
).filter(post_count__gt=0)# 值列表
usernames = User.objects.values_list('username', flat=True)
user_data = User.objects.values('username', 'email')# 选择相关对象(减少查询)
users_with_posts = User.objects.select_related('profile').prefetch_related('posts')# 原生SQL查询
from django.db import connectionwith connection.cursor() as cursor:cursor.execute("SELECT * FROM myapp_user WHERE age > %s", [18])rows = cursor.fetchall()# 使用raw方法
users = User.objects.raw('SELECT * FROM myapp_user WHERE is_active = %s', [True])

查询性能优化

python

# 不好的查询 - N+1 问题
users = User.objects.all()
for user in users:print(user.profile.bio)  # 每次循环都会查询数据库# 好的查询 - 使用select_related
users = User.objects.select_related('profile').all()
for user in users:print(user.profile.bio)  # 一次性查询# 使用prefetch_related处理多对多关系
posts = Post.objects.prefetch_related('tags').all()
for post in posts:print(post.tags.all())  # 一次性预加载

数据库关系

一对一关系

python

class UserProfile(models.Model):user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='profile')bio = models.TextField(blank=True)location = models.CharField(max_length=100, blank=True)def __str__(self):return f"{self.user.username}的档案"# 使用示例
user = User.objects.get(id=1)
profile = user.profile  # 通过related_name访问

一对多关系

python

class Post(TimestampModel):author = models.ForeignKey(User,on_delete=models.CASCADE,related_name='posts')title = models.CharField(max_length=200)content = models.TextField()is_published = models.BooleanField(default=False)class Meta:ordering = ['-created_at']def __str__(self):return self.title# 使用示例
user = User.objects.get(id=1)
user_posts = user.posts.all()  # 用户的所有文章
latest_post = user.posts.first()

多对多关系

python

class Tag(models.Model):name = models.CharField(max_length=50, unique=True)created_at = models.DateTimeField(auto_now_add=True)def __str__(self):return self.nameclass Post(TimestampModel):# ... 其他字段tags = models.ManyToManyField(Tag,related_name='posts',blank=True)def get_tag_names(self):return list(self.tags.values_list('name', flat=True))# 使用示例
post = Post.objects.get(id=1)
post.tags.add(tag1, tag2)  # 添加标签
post.tags.remove(tag1)     # 移除标签
post.tags.clear()          # 清空所有标签

自定义中间表

python

class PostTag(models.Model):post = models.ForeignKey(Post, on_delete=models.CASCADE)tag = models.ForeignKey(Tag, on_delete=models.CASCADE)added_by = models.ForeignKey(User, on_delete=models.CASCADE)added_at = models.DateTimeField(auto_now_add=True)class Meta:unique_together = ['post', 'tag']class Post(models.Model):tags = models.ManyToManyField(Tag,through='PostTag',related_name='posts')

数据库优化

索引优化

python

class User(models.Model):username = models.CharField(max_length=50, db_index=True)email = models.EmailField(unique=True)class Meta:indexes = [models.Index(fields=['username', 'email']),models.Index(fields=['-created_at']),]

查询优化技巧

python

# 1. 使用only和defer选择特定字段
users = User.objects.only('username', 'email')  # 只查询指定字段
users = User.objects.defer('bio')  # 排除指定字段# 2. 使用exists检查存在性
if User.objects.filter(username='john').exists():# 处理逻辑# 3. 使用count获取数量
user_count = User.objects.count()# 4. 使用bulk操作
users = [User(username=f'user{i}') for i in range(1000)]
User.objects.bulk_create(users)  # 批量创建# 5. 使用update批量更新
User.objects.filter(is_active=False).update(is_active=True)

数据库连接池

python

# 使用django-db-connection-pool
DATABASES = {'default': {'ENGINE': 'dj_db_conn_pool.backends.mysql','NAME': 'mydatabase','POOL_OPTIONS': {'POOL_SIZE': 10,'MAX_OVERFLOW': 20,'RECYCLE': 3600,}}
}

生产环境部署

数据库备份

python

# management/commands/backup_database.py
from django.core.management.base import BaseCommand
from django.conf import settings
import subprocess
import os
from datetime import datetimeclass Command(BaseCommand):help = '备份数据库'def handle(self, *args, **options):timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')backup_file = f'backup_{timestamp}.sql'if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql':cmd = ['pg_dump','-h', settings.DATABASES['default']['HOST'],'-U', settings.DATABASES['default']['USER'],'-d', settings.DATABASES['default']['NAME'],'-f', backup_file]env = os.environ.copy()env['PGPASSWORD'] = settings.DATABASES['default']['PASSWORD']subprocess.run(cmd, env=env)self.stdout.write(self.style.SUCCESS(f'备份完成: {backup_file}'))

数据库监控

python

# 使用Django Debug Toolbar
INSTALLED_APPS = [# ...'debug_toolbar',
]MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware',# ...
]# 数据库查询日志
LOGGING = {'version': 1,'handlers': {'console': {'level': 'DEBUG','class': 'logging.StreamHandler',},},'loggers': {'django.db.backends': {'level': 'DEBUG','handlers': ['console'],}}
}

生产环境配置

python

# settings/production.py
DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql','NAME': os.getenv('DB_NAME'),'USER': os.getenv('DB_USER'),'PASSWORD': os.getenv('DB_PASSWORD'),'HOST': os.getenv('DB_HOST'),'PORT': os.getenv('DB_PORT', '5432'),'CONN_MAX_AGE': 600,'OPTIONS': {'sslmode': 'require',}}
}# 数据库性能配置
DATABASES['default']['ATOMIC_REQUESTS'] = False  # 提高性能
DATABASES['default']['AUTOCOMMIT'] = True

数据库健康检查

python

# health_checks.py
from django.db import connection
from django.http import JsonResponsedef database_health_check(request):try:with connection.cursor() as cursor:cursor.execute("SELECT 1")result = cursor.fetchone()if result[0] == 1:return JsonResponse({'status': 'healthy'})else:return JsonResponse({'status': 'unhealthy'}, status=500)except Exception as e:return JsonResponse({'status': 'error', 'message': str(e)}, status=500)

总结

数据库是Web应用的核心组件,正确的数据库设计和优化对应用性能至关重要。Django提供了强大的ORM系统,使得数据库操作更加简单和安全。通过合理的模型设计、查询优化和适当的数据库配置,可以构建出高性能、可扩展的Web应用。

记住以下最佳实践:

  1. 合理设计数据库关系

  2. 为常用查询字段添加索引

  3. 使用select_related和prefetch_related优化查询

  4. 定期备份数据库

  5. 在生产环境使用连接池

  6. 监控数据库性能

  7. 使用迁移管理数据库结构变更

通过掌握这些数据库知识,您将能够构建出更加健壮和高效的Django应用。

http://www.dtcms.com/a/449648.html

相关文章:

  • 福建设计招聘网站seo sem什么意思
  • 用scala做的网站视频网址链接哪里找
  • 基于pyqt5实现的视频抽帧工具源码+项目说明用于目标检测图片采集
  • 浙江省建设局房管科网站建筑模板915 1830价格
  • 怎么做公司官方网站苏州教育网站建设
  • AI Agent:重塑未来智能的核心驱动力
  • node-red 采集CNC?
  • Linux驱动开发与BuildRoot是什么关系与其的应用场景
  • 如何自己做企业网站网站建设与开发的论文
  • Windows批处理进阶使用教程
  • 中秋佳节与 Java 的奇妙联想
  • 评委打分算法解析:从基础实现到性能优化(洛谷)
  • k8s中Pod和Node的故事(2):优先级、抢占和驱逐
  • 网站架构包含哪几部分苏州网站建设网站制作的公司
  • UML笔记 之 事物和关系
  • 中国黄金集团建设有限公司官方网站照片在线编辑
  • 从零开始学习Python Django:从环境搭建到第一个 Web 应用
  • Lenovo XiaoXin Pro13 i5-10210U_i7-10710U 黑苹果 EFI
  • 网站建设服务商24小时接单移动应用开发专业学什么
  • 从 0 到 PB 级存储:MinIO 分布式文件系统实战指南与架构解密
  • [人工智能-综述-23]:AI的硬件层以及组成架构、GPU内部以及组成架构
  • 营销型企业网站分pageadmincms
  • JDK安装操作命令(linux)
  • UNIX下C语言编程与实践39-UNIX 定时器:alarm 函数与 setitimer 函数的使用与对比
  • 18款禁用网站app全部用asp.net 做网站
  • 对比网站中国最大免费wap网站
  • 虚拟麦克风驱动下载
  • 算法题(227):回文字符串
  • 框架--SpringBoot
  • STM32F103 MPU6500 DMP库姿态解算