首页 > 数据库 >BBS数据库表结构设计

BBS数据库表结构设计

时间:2023-05-08 23:33:45浏览次数:39  
标签:name models text 数据库 help True BBS 结构设计 verbose

BBS数据库表结构设计

在我们分析完一个项目的需求之后,我们着手开发项目所需要做的第一件事就是设计数据库的表结构及其字段。

一般来说,设计一个数据库的表结构一般要注意以下三点:

  • 第一,把项目的需求转化为一个个数据库中的表
  • 第二,探寻表与表之间的关联关系
  • 第三,牢记以下原则:能用多对多关联关系就尽量不要用一对多关联关系,能用一对多关联关系就尽量别用一对一(原因是为了减少耦合)

一、用户表:UserInfo

(通过继承AbstractUser类来扩写Auth_user)
•phone:用户的联系方式
•bg_img: 用户的主页背景
•province: 用户的省份
•city: 用户的城市
•gender : 用户的性别
•avatar:用户的头像
•blog:用户的博客站点(外键一对一关联博客表Blog)

二、博客表:Blog

•title:博客标题
•subtitle: 博客子标题
•style:博客样式

三、文章表:Article

•title:文章标题
•head_img: 头像
•description:文章摘要
•content:文章内容
•create_time:文章的创建时间
•modify_time:  文章的修改时间
•up_num :点赞数
•down_num:点踩数
•comment_num:评论数
•blog:属于哪个博客站点(外键关联博客表Blog)
•category:属于哪个分类(外键关联分类表Category)

四、标签表:Tag

•name:标签名
•blog:属于哪个博客站点(外键关联博客表Blog)

五、分类表:Category

•name:分类名
•blog:属于哪个博客站点(外键关联博客表Blog)

六、评论表:Comment

•user:评论的用户(外键关联用户表UserInfo)
•article:该评论属于哪篇文章(外键关联文章表Article)
•content:评论内容
•comment_time: 评论的创建时间
•comment_id:评论的目标id(外键进行自关联)

七、点赞点踩表:UpAndDown

•user:来自哪个用户(外键关联用户表UserInfo)
•article:属于哪篇文章(外键关联文章表Article)
•is_up:点赞还是点踩(根据bool值来判断)
•create_time : 点赞或踩的时间

八、文章标签表: Tag2Article

根据文章与标签的多对多关系手动建立的第三张表
•	tag:标签名(外键关联标签表Tag)
•	article:属于哪篇文章(外键关联文章表Article)

九、轮播图表 Swiper (拓展)

•	image: 轮播图图片名
•	title:轮播图标题
•	img_url: 点击轮播图要跳转的url地址

十、日志表: Log(拓展)

•	id: 日志id
•	ip: 访问的ip地址
•	time: 访问的时间
•	url: 访问的url
•	device: 访问的浏览器
•	platform:访问的操作系统类型

十一、创建BBS表模型

我们要在app中的模型层models.py中写入以下orm语句模型来创建表模型

from django.contrib.auth.models import AbstractUser
from django.utils.html import mark_safe
from django.db import models
from markdown import markdown


# 日志表
class Log(models.Model):
    id = models.AutoField(primary_key=True)
    ip = models.CharField(max_length=64, verbose_name='访问IP', help_text='访问用户的IP地址')
    time = models.DateTimeField(auto_now_add=True, verbose_name='访问时间', help_text='该用户的访问时刻')
    url = models.CharField(max_length=64, verbose_name='访问的URL', help_text='该用户访问的URL地址')
    device = models.CharField(max_length=256, null=True, verbose_name='访问的浏览器', help_text='该用户是用什么浏览器访问的')
    platform = models.CharField(max_length=256, null=True, verbose_name='访问的系统', help_text='该用户用的是什么操作系统')
    # 定义这个表中默认显示的字段
    def __str__(self):
        return self.ip
    # 定义这个表在admin后台中显示的别名
    class Meta:
        ordering = ['id']
        verbose_name_plural = '日志'


# 用户表
class UserInfo(AbstractUser):
    avatar = models.FileField(upload_to='avatar/', default='avatar/default.png', verbose_name='头像', help_text='该用户的头像')
    bg_img = models.FileField(upload_to='bg_img/', default='bg_img/default_bg.png', verbose_name='头像',
                              help_text='该用户的主页背景')
    province = models.CharField(max_length=32, default='', verbose_name='省', help_text='该用户的省')
    city = models.CharField(max_length=32, default='', verbose_name='城市', help_text='该用户的市')
    gender = models.IntegerField(choices=((0, '保密'), (1, '男'), (2, '女')), default=0, verbose_name='性别',
                                 help_text='该用户的性别')
    phone = models.CharField(max_length=11, null=True, default='', verbose_name='联系方式', help_text='该用户的联系方式')
    blog = models.OneToOneField(to='Blog', on_delete=models.CASCADE, null=True, verbose_name='博客', help_text='该用户的博客')

    def __str__(self):
        return self.username

    class Meta:
        verbose_name_plural = '用户'


# 博客表(个人站点)
class Blog(models.Model):
    title = models.CharField(max_length=32, verbose_name='博主昵称', help_text='博主昵称')
    subtitle = models.CharField(max_length=32, verbose_name='子标题/公告', help_text='博客的子标题/公告')
    style = models.CharField(max_length=32, verbose_name='样式', help_text='该博客独有的样式')  # 此处未启用

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = '博客站点'


# 文章表
class Article(models.Model):
    title = models.CharField(max_length=32, verbose_name='标题', help_text='文章的标题')
    head_img = models.FileField(upload_to='article_head_img/', default='article_head_img/default_head.png',
                                verbose_name='头图',
                                help_text='文章的头图')
    description = models.CharField(max_length=128, verbose_name='摘要', help_text='简要描述该文章')
    content = models.TextField(verbose_name='内容', help_text='文章的内容')
    markdown = models.TextField(verbose_name='Markdown内容', default='暂无', help_text='文章的Markdown内容')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='该文章的创建时间')
    modify_time = models.DateTimeField(auto_now=True, verbose_name='修改时间', help_text='该文章的最后修改时间')
    up_num = models.IntegerField(default=0, verbose_name='点赞数', help_text='该文章的点赞数')
    down_num = models.IntegerField(default=0, verbose_name='点踩数', help_text='该文章的点踩数')
    comment_num = models.IntegerField(default=0, verbose_name='评论数', help_text='该文章的评论数')
    blog = models.ForeignKey(to='Blog', on_delete=models.CASCADE, null=True, blank=True, verbose_name='博客',
                             help_text='该文章属于哪个博客页面')
    category = models.ForeignKey(to='Category', on_delete=models.CASCADE, null=True, blank=True, verbose_name='分类',
                                 help_text='该文章属于哪个分类')
    tag = models.ManyToManyField(to='Tag', through='Tag2Article',
                                 through_fields=('article', 'tag'), verbose_name='标签',
                                 help_text='该文章有哪些标签')

    def get_text_md(self):
        return mark_safe(markdown(self.content))

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = '文章'
        ordering = ['id', ]


# 标签表
class Tag(models.Model):
    name = models.CharField(max_length=32, verbose_name='标签', help_text='标签的名字')
    blog = models.ForeignKey(to='Blog', on_delete=models.DO_NOTHING, null=True, blank=True, verbose_name='博客',
                             help_text='该标签属于哪个博客页面')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = '标签'


# 分类表
class Category(models.Model):
    name = models.CharField(max_length=32, verbose_name='分类', help_text='分类的名称')
    blog = models.ForeignKey(to='Blog', on_delete=models.DO_NOTHING, null=True, blank=True, verbose_name='博客',
                             help_text='该分类属于哪个博客页面')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = '分类'


# 评论表
class Comment(models.Model):
    user = models.ForeignKey(to='UserInfo', on_delete=models.DO_NOTHING, verbose_name='用户', help_text='该评论来自哪个用户')
    article = models.ForeignKey(to='Article', on_delete=models.CASCADE, null=True, verbose_name='文章',
                                help_text='评论的对象是哪篇文章')
    content = models.CharField(max_length=256, verbose_name='内容', help_text='评论的内容')
    comment_time = models.DateTimeField(auto_now_add=True, verbose_name='时间', help_text='评论的时间')
    comment_id = models.ForeignKey(to='self', on_delete=models.CASCADE, null=True, verbose_name='评论id',
                                   help_text='对哪个id的评论进行评论')

    def __str__(self):
        return self.content

    class Meta:
        verbose_name_plural = '评论'


# 点赞点踩
class UpAndDown(models.Model):
    user = models.ForeignKey(to='UserInfo', on_delete=models.CASCADE, verbose_name='用户', help_text='来自哪个用户')
    article = models.ForeignKey(to='Article', on_delete=models.CASCADE, null=True, verbose_name='文章',
                                help_text='针对哪篇文章')
    is_up = models.BooleanField(null=True, verbose_name='点赞点踩', help_text='True为点赞,False为点踩')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='点赞点踩的时间')

    def __str__(self):
        return self.user

    class Meta:
        verbose_name_plural = '点赞点踩'


# 标签、文章关联表
class Tag2Article(models.Model):
    tag = models.ForeignKey(to='Tag', on_delete=models.SET_DEFAULT, default='', verbose_name='标签', help_text='关联的标签')
    article = models.ForeignKey(to='Article', on_delete=models.CASCADE, default='', verbose_name='文章',
                                help_text='关联的文章')

    class Meta:
        verbose_name_plural = '标签关联文章'


# 轮播图表
class Swiper(models.Model):
    image = models.FileField(upload_to='swiper_img/', default='swiper_img/default.jpg', verbose_name='图片',
                             help_text='轮播图的图片')
    title = models.CharField(max_length=32, verbose_name='标题', help_text='图片的标题')
    img_url = models.CharField(max_length=64, verbose_name='URL', help_text='点击图片要跳转的URL地址')

    def __str__(self):
        return self.img_url

    class Meta:
        verbose_name_plural = '轮播图'

关于这张表中建立的模型(models.py),我们还会在下文中反复提到。

django1表设计

from django.db import models

# Create your models here.
"""
先写普通字段
之后再写外键字段
"""
from django.contrib.auth.models import AbstractUser


class UserInfo(AbstractUser):
    phone = models.BigIntegerField(verbose_name='手机号',null=True)
    # 头像
    avatar = models.FileField(upload_to='avatar/',default='avatar/default.png',verbose_name='用户头像')
    """
    给avatar字段传文件对象 该文件会自动存储到avatar文件下 然后avatar字段只保存文件路径avatar/default.png
    """
    create_time = models.DateField(auto_now_add=True)

    blog = models.OneToOneField(to='Blog',null=True)


class Blog(models.Model):
    site_name = models.CharField(verbose_name='站点名称',max_length=32)
    site_title = models.CharField(verbose_name='站点标题',max_length=32)
    # 简单模拟 带你认识样式内部原理的操作
    site_theme = models.CharField(verbose_name='站点样式',max_length=64)  # 存css/js的文件路径


class Category(models.Model):
    name = models.CharField(verbose_name='文章分类',max_length=32)
    blog = models.ForeignKey(to='Blog',null=True)


class Tag(models.Model):
    name = models.CharField(verbose_name='文章标签',max_length=32)
    blog = models.ForeignKey(to='Blog', null=True)


class Article(models.Model):
    title = models.CharField(verbose_name='文章标题',max_length=64)
    desc = models.CharField(verbose_name='文章简介',max_length=255)
    # 文章内容有很多 一般情况下都是使用TextField
    content = models.TextField(verbose_name='文章内容')
    create_time = models.DateField(auto_now_add=True)

    # 数据库字段设计优化
    up_num = models.BigIntegerField(verbose_name='点赞数',default=0)
    down_num = models.BigIntegerField(verbose_name='点踩数',default=0)
    comment_num = models.BigIntegerField(verbose_name='评论数',default=0)

    # 外键字段
    blog = models.ForeignKey(to='Blog', null=True)
    category = models.ForeignKey(to='Category',null=True)
    tags = models.ManyToManyField(to='Tag',
                                  through='Article2Tag',
                                  through_fields=('article','tag')
                                  )


class Article2Tag(models.Model):
    article = models.ForeignKey(to='Article')
    tag = models.ForeignKey(to='Tag')


class UpAndDown(models.Model):
    user = models.ForeignKey(to='UserInfo')
    article = models.ForeignKey(to='Article')
    is_up = models.BooleanField()  # 传布尔值 存0/1


class Comment(models.Model):
    user = models.ForeignKey(to='UserInfo')
    article = models.ForeignKey(to='Article')
    content = models.CharField(verbose_name='评论内容',max_length=255)
    comment_time = models.DateTimeField(verbose_name='评论时间',auto_now_add=True)
    # 自关联
    parent = models.ForeignKey(to='self',null=True)  # 有些评论就是根评论

十二、数据库配置以及迁移

在这个项目中,我们使用pycharm自带的sqlite3,因此无需额外在设置中配置数据库,但是每当我们对models.py中的内容进行修改时,仍要进行数据库迁移

在pycharm左下角的终端terminal中输入以下两条命令完成迁移

生成迁移文件

python3 manage.py makemigrations

数据库迁移

python3 manage.py migrate

标签:name,models,text,数据库,help,True,BBS,结构设计,verbose
From: https://www.cnblogs.com/ycmyay/p/17383518.html

相关文章

  • SQL Server数据库判断最近一次的备份执行结果
    1麻烦的地方在SQLServer的官方文档里面可以看到备份和还原的表,但是这些表里面只能找到备份成功的相关信息,无法找到备份失败的记录,比如msdb.dbo.backupset。对于一些监控系统未监控作业的情况下,想要监控数据库备份任务执行失败而触发告警规则,有些麻烦。但是SQLserver内部是可......
  • java基于ssm的求职招聘管理系统、校园求职招聘管理系统,附源码+数据库,适合毕业设计、课
    1、项目介绍​该求职招聘网站基于B/S架构,采用SSM框架,运用JSP网页开发技术,并结合MySQL数据库,为招聘者和求职者搭建了一个高效、便捷的网络招聘平台。系统总共有三个角色:求职者、招聘者、管理员​本系统分别为前台求职招聘和后台系统管理,功能如下:​1.前台求职招聘​前台首......
  • 数据库优化
    数据库优化一、数据库硬件优化(选型)1.一般数据库选择1.真实的硬件,物理机2.云产品ECS,自己搭建数据库3.云数据库(RDS、DRDS)2.数据库类型1.OLTP在线事务处理系统 支持大量并发用户定期添加和修改数据。 反映随时变化的单位状态,但不保存其历史记录。 包含大量数据,其中包括......
  • 数据库读现象
    一数据库读现象数据库管理软件的“读现象”指的是当多个事务并发执行时,在读取数据方面可能碰到的问题,包括有脏读、不可重复读和幻读。ps:对于一些数据库管理软件会自带相应的机制去解决脏读、不可重复读、幻读等问题,因为这些自带的机制,下述的一些实验现象可能在某一数据库管理软......
  • 数据库简介
    一数据库管理软件的由来基于我们之前所学,数据要想永久保存,都是保存于文件中,毫无疑问,一个文件仅仅只能存在于某一台机器上。如果我们暂且忽略直接基于文件来存取数据的效率问题,并且假设程序所有的组件都运行在一台机器上,那么用文件存取数据,并没有问题。很不幸,这些假设都是你自......
  • 数据库的四大特性和事务隔离级别
    数据库中经常被问到四大特性和隔离级别,一般都是涉及到概念性问题,在此做一些整理总结,方便理解。1、事务的隔离级别由低到高依次为Readuncommitted(未授权读取、读未提交)、Readcommitted(授权读取、读提交)、Repeatableread(可重复读取)、Serializable(序列化),这四个级别可以逐个解决脏......
  • (python) 数据库一次 Connection 连接,不同 cursor
    数据库一次Connection连接,不同cursor的最简洁代码:importpymysqlclassDatabase(object):connection=Nonedef__init__(self):ifnotDatabase.connection:Database.connection=pymysql.connect(host="127.0.0.1",......
  • TSBS 是什么?为什么时序数据库 TDengine 会选择它作为性能对比测试平台?
    去年8月我们在TDengine开发者大会上正式发布了TDengine3.0,TDengine也由此升级成为了一款云原生时序数据库(TimeSeriesDatabase,TSDB)。为了客观、准确、有效地评估TDengine3.0的性能指标,我们决定使用TSBS(TimeSeriesBenchmarkSuite)作为基准性能测试平台,针对DevOps......
  • 初识数据库
    楔子假设现在你已经是某大型互联网公司的高级程序员,让你写一个火车票购票系统,来hold住十一期间全国的购票需求,你怎么写?由于在同一时段抢票的人数太多,所以你的程序不可能写在一台机器上,应该是多台机器一起分担用户的购票请求。那么问题就来了,票务信息的数据存在哪里......
  • 数据库的创建、数据表的创建
     创建数据库usemaster--表示下面的操作是真的master数据库完成的go--判断当前数据库是否在master数据库中已经存在ifexists(select*fromsysdatabaseswherename='MISDB')dropdatabaseMISDBgo--创建数据库createdatabaseMISDBonprimary(name='MISDB_m......