设计用户模块的schema

news2025/1/7 13:46:40

schema

在计算机科学中,schema通常指的是 数据结构的定义约束

关系型数据库

在关系型数据库中,schema指的是数据库中所有表格的定义和表格之间的关系约束,包括每个表格的列名、数据类型、主键、外键等等。

如果要对一个关系型数据库进行查询或修改操作,就必须先定义好相应的schema。

NoSQL数据库

在NoSQL数据库中,schema的概念略有不同。

NoSQL数据库通常分为:

  • 文档型数据库、
  • 键-值型数据库、
  • 列族存储型数据库
  • 图形数据库等几种类型

在这些数据库中,schema可以理解为数据模型的定义。

与关系型数据库相比,NoSQL数据库更加灵活,允许存储非结构化或半结构化数据,因此其schema通常也比较宽松。

例如,在MongoDB中,用于定义模型的工具Mongoose提供了对数据模型的定义和约束,包括集合(类似于关系型数据库的表)和文档的字段、数据类型、索引等方面的约束。

MongoDB 中 schema (“模型”)

MongoDB是一种非关系型数据库,它没有传统意义上的“schema”概念。

相比于关系型数据库中需要在创建表时定义固定的列(字段)和数据类型,MongoDB存储的文档可以包含各种不同结构的数据,每个文档的字段也可以动态添加或删除。

而在使用MongoDB时,我们通常需要确保应用程序对文档中所需数据存在一些共同的约定,比如使用相同的字段名、数据类型等,以便于应用程序能够正确地解析和使用这些数据。

这些约定可以称之为 “模型”,这也是在MongoDB中最接近于“schema”的概念。

在MongoDB中通常会使用Mongoose这样的工具来定义数据模型,其中包括对于集合(类似于关系型数据库的表)和文档的字段、数据类型、索引等方面的约束。

但是这些约束是可选的,同时也可以在运行时进行修改。

因此,MongoDB更加灵活,适用于需要频繁变化的数据结构或者不确定的数据模型场景。

更多精彩内容,请微信搜索“前端爱好者戳我 查看

上面说过在 MongoDB 中,模型是由 Schema 对象 定义的数据结构。 那么Schema到底是什么?

Schema 是一个 JavaScript 对象,定义了文档中字段的类型、验证规则、默认值等属性。

通过定义 Schema,可以为文档指定一组预定义的属性和方法,使文档更加结构化和可靠。

在创建模型时,我们需要将定义好的 Schema 作为参数传入 Mongoose 的 model() 方法中,以便 Mongoose 将其编译为模型。

模型可以被视为与数据库交互的对象,可以用来执行 CRUD 操作,查询文档,更新文档等操作。

在使用 MongoDB 和 Mongoose 进行开发时,定义模型并使用它们来操作数据是非常常见的操作。

通常情况下,我们会根据实际需求定义多个不同的模型,每个模型对应一种数据类型,以便更好地组织和管理数据。

设计用户模块的schema

用户模块

用户模块是指在程序中负责**管理用户信息权限**的模块。

该模块通常包括以下功能:

  • 用户注册登录:允许用户通过输入用户名和密码等信息注册新用户,或使用已有账号进行登录。
  • 用户信息管理:可以编辑和查看用户信息,例如昵称、邮箱、头像等。
  • 权限管理:对于不同的用户角色,可以控制其所能访问的页面、功能,以及具体的操作权限。
  • 安全性管理:保护用户数据安全,包括防止SQL注入、XSS攻击等攻击方式,并对用户密码等敏感信息进行加密存储。
  • 第三方登录:支持用户通过第三方平台(如微信、QQ、微博)进行快捷登录,并绑定相应账号。
  • 记住密码自动登录:可以让用户在下次登录时自动填写用户名和密码,提高用户体验。

在实现用户模块时,需要先设计数据库表结构,包括用户信息表、角色表、权限表、登录日志表等,并根据业务需求实现相应的API接口和前端页面。

同时,需要考虑到用户数据的安全性和隐私保护,例如对密码进行加密存储,采用HTTPS协议传输数据等措施。

下面仅说一下用户信息表的schema。

开始之前,先介绍mongoose创建schema中用到的几个api

mongoose.Schema()

mongoose.Schema()是Mongoose中用于定义MongoDB文档结构的构造函数。

通过它,可以创建一个新的Schema对象,用于约束MongoDB集合中文档的结构和属性。

在定义Schema时,可以使用各种类型的数据,包括:

  • 字符串
  • 数字
  • 日期等基本类型
  • 嵌套其他Schema对象或者数组,
  • 添加虚拟属性等。

此外,还可以为每个字段配置默认值验证规则索引等属性,以及自定义实例方法和静态方法。

mongoose.model()

mongoose.model()是Mongoose中用于创建数据模型的方法。

数据模型是用来定义MongoDB集合(类似于关系型数据库中的表)中文档结构、字段类型、默认值、验证规则等的约束条件。

使用mongoose.model()方法,可以将一个JavaScript对象转换为Mongoose的数据模型。

该方法接受两个参数:

  • 第一个参数为模型名称(对应MongoDB集合名称),
  • 第二个参数为模型定义对象。

其中,模型定义对象通常包括以下属性:

  • 字段名:每个字段都可以指定其类型、默认值、验证规则、索引等属性。
  • 静态方法:在数据模型上定义静态方法,可通过模型名称调用。
  • 实例方法:在数据模型原型上定义实例方法,在每个文档对象上都可以调用。
  • 虚拟属性:在文档对象中定义虚拟属性,它们不会被存储到数据库中,而是由其他字段计算得出。

设计用户模块的schema

第一步:在项目根目录新建models文件夹用于存储models文件

第二步:在models文件夹内新建用户模块的schema – users.js

需要进行下面步骤:

  1. 导入mongoose – let mongoose = require('mongoose')
  2. 实例化Schema – let schema = new mongoose.Schema()
  3. 创建模型对象 – let Users = mongoose.model('users', schema) – 第一个参数为模型名称(对应MongoDB集合名称,第二个参数为模型定义对象(规则)
  4. 导出模型对象 – module.exports = Users

全部代码

//  导入mongoose 
let mongoose = require('mongoose')

// 实例化Schema
const userSchema = new mongoose.Schema({
    username: String,
    pwd: String
})

// 创建模型对象
const User = mongoose.model('users', userSchema)

// 导出模型对象
module.exports = Users

第三步:在路由中使用用户模块的schema – users.js

var router = require('koa-router')();

const Users = require('../models/users') // 引入users modal 

router.prefix('/users');

// 添加系统用户 
router.post('/add', async (ctx) => {
  let { username, pwd } = ctx.request.body
  await Users.create({ username, pwd }).then(rel => {
    if (rel) {
      ctx.body = {
        code: 200,
        msg: '添加成功',
        data: rel
      }
    } else {
      ctx.body = {
        code: 300,
        msg: '添加失败'
      }
    }

  }).catch(err => {
    ctx.body = {
      code: 400,
      msg: '添加时出现异常'
    }
    console.error(err)
  })

})

module.exports = router;

在上面的示例代码中,在路由文件users中使用const Users = require('../models/users') , 引入users modal。

添加系统用户调用使用users modal模块。

其他复杂实例

实例一

// userSchema
const mongoose = require('mongoose');

// 创建用户Schema
const userSchema = new mongoose.Schema({
    username: {
        type: String,
        required: true, // 必填项
        unique: true,   // 唯一索引
        lowercase: true // 存入数据库前将其转换为小写
    },
    password: {
        type: String,
        required: true,
        select: false    // 查询时不返回该字段
    },
    email: {
        type: String,
        required: true,
        match: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
        unique: true
    },
    age: {
        type: Number,
        min: 18,         // 最小值
        max: 60          // 最大值
    },
    created: {
      type: Date,
      default: Date.now
    },
    friends: [{
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    }]
});

// 创建虚拟属性
userSchema.virtual('fullName').get(function() {
    return this.firstName + ' ' + this.lastName;
});

// 创建实例方法
userSchema.methods.sayHello = function() {
    console.log(`Hello, ${this.username}!`);
}

// 创建静态方法
userSchema.statics.findByUsername = function(username, callback) {
    return this.findOne({ username: username }, callback);
}

// 导出用户Schema
module.exports = userSchema;

在上面的示例代码中,首先创建了一个用户Schema对象,并为其定义了username、password、email、age、created和friends属性。

每个属性都有其特定的类型和属性,如数据类型、是否必填、最大值最小值、正则表达式等。

然后,通过virtual方法创建一个fullName虚拟属性,以及methods方法创建一个sayHello实例方法,statics方法创建一个findByUsername静态方法。

最后,将该Schema对象导出供其他文件使用。

使用Schema对象创建mongoose数据模型时,需要在第二个参数传入该Schema对象,如下所示:

// models/user
const mongoose = require('mongoose');
const userSchema = require('./userSchema');

const User = mongoose.model('User', userSchema);

module.exports = User;

这样,在其他文件中引用此模型即可,如下所示:

const User = require('./models/user');

const user = new User({
  username: 'admin',
  password: '123456',
  email: 'admin@admin.com',
  age: 27
});

user.save(function(err, doc) {
  if (err) {
    console.error(err);
  } else {
    console.log(doc);
  }
});

实例二

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// 创建用户数据模型
const UserSchema = new Schema({
  name: { type: String, required: true },
  age: { type: Number, default: 18 },
  email: { type: String, required: true },
  password: { type: String, required: true },
  createdAt: { type: Date, default: Date.now }
});

// 创建模型并导出
module.exports = mongoose.model('User', UserSchema);

上述代码中,首先使用mongoose.Schema()方法定义了一个用户数据模型的结构,并将其存储在UserSchema中。

然后使用mongoose.model()方法,将UserSchema转换为一个名为“User”的model对象,并导出该对象。

这样,在其他的文件中就可以通过require()方法来引用该model对象,并进行MongoDB数据库的操作了。

例如:

const mongoose = require('mongoose');
const User = require('./models/user');

mongoose.connect('mongodb://localhost/test');
const db = mongoose.connection;

db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  console.log('Connected to MongoDB');

  // 创建一个新用户
  const user = new User({
    name: 'Alice',
    age: 20,
    email: 'alice@example.com',
    password: '123456'
  });

  // 将新用户保存到集合中
  user.save(function(err, doc) {
    if (err) return console.error(err);
    console.log(doc);
  });
});

在上述示例代码中,首先使用mongoose.connect()方法连接了MongoDB数据库,然后使用require()方法引入了之前定义的User模型。

接着创建了一个新用户对象,并调用save()方法将其保存到数据库中。

每日一课:正则表达式

正则表达式是一个用于匹配文本的模式,可以使用特定的语法规则来表示各种匹配模式。

在JavaScript中,可以使用RegExp对象来创建和操作正则表达式。

正则表达式可以用于各种字符串处理任务,例如搜索、替换、验证等。

下面是一些基本的正则表达式概念:

  • 字符集:用于匹配一组字符中的任何一个字符。例如,[abc]可以匹配a、b或c,还可以使用范围表示法[a-z]、 [^abc]表示不匹配a、b和c。
  • 元字符:用于表示特殊字符或者特殊的用途。一些常见的元字符包括.、*、+、?、\、|、^、$、(、)等。
  • 量词:用于指定匹配次数。例如,?表示零次或一次,*表示零次或多次,+表示一次或多次,{n}表示恰好匹配n次,{n,m}表示匹配n到m次。
  • 边界匹配符:用于匹配字符串的边界,例如^表示匹配字符串的开头,$表示匹配字符串的结尾。

下面是一些示例正则表达式及其含义:

  • /a/:匹配字符串中第一个出现的字符a。
  • /abc/:匹配字符串中连续出现的字符串abc。
  • /\d/:匹配一个数字字符。
  • /\w/:匹配一个字母、数字或下划线字符。
  • /^[a-z]+$/:匹配只包含小写字母的字符串。
  • /^\d{3}\-\d{3}\-\d{4}$/:匹配电话号码格式,例如123-456-7890。

在JavaScript中,可以使用RegExp对象的构造函数或者字面量语法来创建正则表达式。

例如:

// 通过RegExp构造函数创建正则表达式
const pattern1 = new RegExp('ab+c');

// 通过字面量语法创建正则表达式
const pattern2 = /ab+c/;

然后可以使用正则表达式的各种方法,如test()、exec()等,进行文本匹配和替换操作,

const str = 'Hello, world!';
const pattern = /world/;
console.log(pattern.test(str)); // true
console.log(str.replace(pattern, 'JavaScript')); // Hello, JavaScript!

例如:

const str = 'Hello, world!';
const pattern = /world/;
console.log(pattern.test(str)); // true
console.log(str.replace(pattern, 'JavaScript')); // Hello, JavaScript!

正则表达式是一种强大的工具,用于处理各种文本匹配、替换、验证等任务。在JavaScript中,可以使用RegExp对象进行正则表达式操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/644606.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在没有实验数据的情况下,如何高效快速发表论文

文献计量学是指用数学和统计学的方法,定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体,注重量化的综合性知识体系。特别是,信息可视化技术手段和方法的运用,可直观的展示主题的研究发展历程、研究现状、研究…

互联网一线大厂Java面试题大全带答案 1110道(持续更新)

前言 春招,秋招,社招,我们 Java 程序员的面试之路,是挺难的,过了 HR,还得被技术面,小刀在去各个厂面试的时候,经常是通宵睡不着觉,头发都脱了一大把,还好最终…

平台稳定性里程碑 | Android 14 Beta 3 发布

作者 / Dave Burke, VP of Engineering 随着今天 Android 14 Beta 3 的发布,我们随之进入到 Android 开发周期的下一个阶段。Beta 3 依旧围绕着我们的核心主题打造,即隐私、安全、性能、开发者生产力和用户定制,同时继续完善平板电脑、可折叠…

基础知识学习---排序算法

1、本栏用来记录社招找工作过程中的内容,包括基础知识学习以及面试问题的记录等,以便于后续个人回顾学习; 暂时只有2023年3月份,第一次社招找工作的过程; 2、个人经历: 研究生期间课题是SLAM在无人机上的应…

Rsync工具的详细介绍以及定时备份案例

RSYNC 什么是RSYNC rsync是类unix下的一款数据镜像备份工具——remote sync。 Rsync 的基本特点如下: 可以镜像保存整个目录树和文件系统;可以很容易做到保持原来文件的权限、时间、软硬链接等;无须特殊权限即可安装;优化的流…

Java中的Lambda表达式详解

文章目录 什么是LambdaLambda表达式的语法Lambda表达式的应用场景GUI应用Lambda表达式的优缺点总结 什么是Lambda java中的Lambda表达式是一种函数式编程的风格,它允许我们将代码作为数据传递,并在需要时执行。Lambda表达式能够极大地简化代码&#xff0…

WPF开发txt阅读器9:语音播放及其进度监控

文章目录 播放进度光标跟踪进度条 txt阅读器系列: 需求分析和文件读写目录提取类💎列表控件与目录字体控件绑定💎前景/背景颜色书籍管理系统💎用树形图管理书籍语音播放 播放进度 SpeechSynthesizer对象可以注册Speech_SpeakPr…

安洵杯SYCCTF2023 writeup

一、MISC 1.sudoku_easy 简单的数独交互,几个小注意点,每次发送level之后sleep5秒才会返回题目 将形如 --------------------- 800103720 023840650 410006008 300001062 000052407 072060090 160000375 205019846 000030000 --------------------- 转换…

django中url和视图函数path re_path views.py

目录 url的定义url的格式django中的urldjango中的创建自己的urldjango访问测试django中的path动态django中的path动态案例django中的path动态类型django中的path动态案例-计算器django的正则路由re_path() url的定义 url 统一资源定位符 url 用来表示互联网上某个资源的地址 …

邀请媒体参加活动的邀请函应该怎么写

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 经常有小伙伴问媒体邀请函怎么写,今天胡老师就把媒体邀请函的一个大概格式分享出来,不论是 做成什么形式的邀请函,这几点都不可少。 主题:…

数据库的基本概念

数据库的基本概念 数据(Data) 描述事物的符号记录 包括数字、文字、图形、声音、档案记录等 以“记录”形式按统一的格式进行存储 表 将不同的记录组织在一起 用来存储具体数据 数据库 表的集合,是存储和管理数据的仓库 数据库管理…

linuxOPS基础_进程查看与管理

进程与程序的关系 进程是正在执行的一个程序或命令,每个进程都是一个运行的实体,并占用一定的系统资源。程序是人使用计算机语言编写的可以实现特定目标或解决特定问题的代码集合。 ​ 简单来说,程序是人使用计算机语言编写的,可…

三菱FX5U系列PLC之间进行简易PLC间链接功能的具体方法

三菱FX5U系列PLC之间进行简易PLC间链接功能的具体方法 功能介绍: 在最多8台FX5U或者FX3U PLC之间通过RS-485通信方式连接,进行软元件相互链接的功能。 接线注意事项: 根据链接模式和所使用的从站数量的不同,链接软元件的占用点数也有所变化。根据链接软元件的起始编号,对占…

Java数据结构之第十五章、Trie(前缀树/单词查找树)

一、前缀树 1.1前缀树相关知识 1.前缀树的概念:前缀树又叫字典树或单词查找树(高效的存储和查找字符串集合的数据结构)。 2.主要应用场景:给定一个字符串集合构建一颗前缀树,然后给定一个字符串,判断前缀…

Flink 流批一体在 Shopee 的大规模实践

摘要:本文整理自 Shopee 研发专家李明昆,在 Flink Forward Asia 2022 流批一体专场的分享。本篇内容主要分为四个部分: 1. 流批一体在 Shopee 的应用场景 2. 批处理能力的生产优化 3. 与离线生态的完全集成 4. 平台在流批一体上的建设和演进 …

华为OD机试 JavaScript 实现【扑克牌大小】【牛客练习题 HJ88】,附详细解题思路

一、题目描述 扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A、2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王&#xff09…

JavaScript笔记——快速了解 ES6 新增数组方法,开箱即用(含案例)

文章目录 📋前言🎯Array.from()🎯Array.of()🎯Array.find()🎯Array.findIndex()🎯Array.includes()🎯Array.flat()🎯Array.flatMap()🎯Array.every()🎯Array.…

MQTT相关知识点

目录 一、简述 二、设计规范 三、MQTT协议原理 3.1 MQTT协议实现方式 3.2 网络传输与应用消息 3.3 MQTT客户端 3.4 MQTT服务器 3.5 MQTT协议中的订阅、主题、会话 3.6 MQTT协议中的方法 四.MQTT脑图 五.体验MQTT 搭建MQTT服务器(Broker) MQT…

MFC 工具栏SOP 线程创建非模式化窗口 实现拓展工具栏

自己在学习工具栏的时候,做的笔记 1 实现基本工具栏 1.1 在Dlg.h文件中声明变量和定义资源ID #define ID_BUTTONS 501CToolBar m_toolbar; //工具栏 CImageList m_imageList; //工具栏图片 CImageList m_hotImageList; //工具栏热点图片 CReBar m_Rebar; //…

Jenkins安装以及部署

本文基于war包形式部署的 需要提前下载Jenkins的war包 Jenkins 的安装和设置下载内容 https://mirrors.jenkins.io/war 版本对应 目录 1.初始化环境 2.安装jdk 安装git Maven配置 安装Jenkins 使用DockerFile的方式进行部署 1.初始化环境 mkdir -p /home/soft 2.安装…