NoSQL设计
常见场景及设计方法
内嵌
是指存在关联关系的文档,放在同一文档中,以数组的形式存放。一对多很少,直接内嵌
1 2 3 4 5 6
| { "username": "brain", "gender": 0, "roles": ["admin", "user"], "address": ["address1", "address2"] }
|
- 减少了关联查询
- 适合与单类需要描述的属性
- 不经常变化的属性(扩展、嵌套关联)
父引用
是指存在一对多的情况中,放在同一文档中,以数组的形式存放
1 2 3 4 5 6 7 8 9 10
| { "tid": "postId", "title": "文章标题", "catalog": "index", "created": "143876589", "comments": [ "commentID1", "commentID2" ] }
|
子引用
是指存在一对非常多的情况中,由于数据库文档存放限制,这个时候进行反向引用
1 2 3 4 5 6 7 8
| { "cid": "commentID", "tid": "postID", "content": "这是回复的内容", "isRead": 0, "isBest": 0, "status": 1 }
|
父子引用设计
- 引用数据内容是否非常多
- 引用数据量是否非常庞大,而且在增加
- 数据是否需要单独访问
反范式
范式是指按既定的用法,范式是一种公认的模型或模式。反范式->不走寻常路
1 2 3 4 5 6 7 8 9 10 11 12
| { "tid": "postID", "title": "文章标题", "created": "1466542881", "users": [ { "uid": "用户ID", "name": "用户昵称", "isVIP": 0 } ] }
|
- 是否有提升性能的区间
- 数据量的变化是否非常庞大,庞大到更新会异常低效
- 先考虑读写比,才考虑反范式
双向关联的场景及设计原则
启动一个mongoDB
参考
1 2 3 4 5 6 7 8 9 10 11 12 13
|
docker run --name mymongo -v /mymongo/data:/data/db -d mongo:4
docker ps
docker logs mymongo
docker pull mongo-express
docker run --link mymongo:mongo -p 8081:8081 mongo-express
|
MongoDB 操作
基本操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| docker exec -it mongo /bin/bash
mongo -uroot -p123 admin
mongo admin 快捷进入mongo的admin权限库 然后 db.auth('root', '123')
mongo MongoDB shell version v4.4.2 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("3c81c8c0-e0c4-4e82-9652-296a090d17c4") } MongoDB server version: 4.4.2 > db.auth('wsr','123456') 1 > show dbs admin 0.000GB config 0.000GB local 0.000GB test 0.000GB > use test switched to db test > show collections runoob user
> db.createUser({user:'test',pwd:'123',roles:[{role:'readWrite',db:'admin'}]}) Successfully added user: { "user" : "test", "roles" : [ { "role" : "readWrite", "db" : "admin" } ] }
> db.auth('test','123') 1
> show users
> db.dropUser('test')
db.updateUser("test",{roles:[ {role:"read",db:"testDB"} ]})
db.updateUser("test",{pwd:"changepass"});
> db.createCollection("goods")
> db.goods.insert({"name": "每日坚果", "price": "89", "num": "100"})
> db.goods.find() > db.数据集名.find({"字段名":"条件"})
db.article.count()
db.article.remove({})
db.dropDatabase()
|
mongodb的三个结构: 数据库db/数据集(集合)collection/文档xxx, 分别对应着mysql中的数据库/数据表/数据记录
备份和恢复
1 2 3 4 5 6 7 8 9 10 11 12 13
| docker exec -it mongo mongodump -h localhost -u root -p password -o /tmp/test
docker cp 容器名:/tmp/test /tmp/test
docker exec -it mongo mongorestore -h localhost -u root -p oassword --dir /tmp/test
docker cp /tmp/test 容器名:/tmp/test
|
Mongoose
分类 |
Mysql |
MongDB |
Mongoose |
1 |
数据库实例 |
MongDB实例 |
Mongoose |
2 |
模式(schema) |
数据库(database) |
mongoose |
3 |
表(table) |
集合(collection) |
模板(Schema)模型(Model) |
4 |
行(table) |
文档(document) |
实例(instance) |
5 |
Primary key |
Object(_id) |
Object(_id) |
6 |
表字段Column |
Field |
Field |
官网
1 2
| npm install -S mongoose npm install -S saslprep
|
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const mongoose = require('mongoose')
mongoose.connect('mongodb://用户名:密码@ip:端口/数据库名称', { userNewUrlParser: true, useUnifiedTopology: true })
const User = mongoose.model('users', {name: String, age: Number, email: String})
const wsr = new User({ name: 'wsr', age: 23, email: 'wangshrl@163.com' })
wsr.save().then(()=>{ console.log('save ok!') })
|
核心概念(Schema、Model)
Schema: 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力。每一个 Schema 对应 MongoDB 中的一个集合(collection)。Schema 中定义了集合中文档(document)的样式。
Model: 由Schema发布生成的模型,具有抽象属性和数据库操作能力
Entity: 由Model创建的实例,也能操作数据库
安装 & 初始化配置
- 配置数据库用户名密码,ip,端口,数据库名
- config/index.js*
1 2 3 4 5
| const DB_URL = 'mongodb://wsr:123456@49.232.90.151:10050/test'
export default{ DB_URL }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import mongoose from 'mongoose' import config from './index'
mongoose.connect(config.DB_URL, { useNewUrlParser: true, useUnifiedTopology: true })
mongoose.connection.on('connected', ()=>{ console.log('mongoose is connected with' + config.DB_URL) })
mongoose.connection.on('error', ()=>{ console.log('mongoose is connected with' + config.DB_URL+ 'is error') })
mongoose.connection.on('disconnected', ()=>{ console.log('mongoose is disconnected with' + config.DB_URL) })
export default mongoose
|
- 测试数据库连接是否成功
- model/test.js*
1 2 3 4 5 6 7 8 9 10 11 12
| import mongoose from '../config/DBHelper'
const Schema = mongoose.Schema
const TestSchema = new Schema({ 'name': { type: String }, 'age': { type: Number } })
const TestModel = mongoose.model('users', TestSchema)
export default TestModel
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import User from './test'
const insertMothod = async () => { const data = new User({ name: 'wsr', age: 18 }) const result = await data.save() console.log(result) }
insertMothod()
const findMothod = async () => { const result = await User.find() console.log(result) }
findMothod()
const updateMothod= async () => { const result = await User.updateOne({name: 'wsr'}, {age: 20}) console.log(result) }
updateMothod()
const deleteMothod= async () => { const result = await User.deleteOne({name: 'wsr'}) console.log(result) }
deleteMothod()
|