1 关系型数据库和非关系型数据库
关系型数据库 (Relational Database) 和非关系型数据库 (Non-relational Database 或 NoSQL Database) 之间的主要区别可以从以下几个方面进行理解:
1.1 数据结构:
关系型数据库:以表格形式存储数据,每个字段(列)具有明确的类型,每个记录(行)都遵循同一种模式。它们使用 SQL(Structured Query Language,结构化查询语言)进行查询。
非关系型数据库:没有固定的数据模式。数据可能被存储为键值对、宽列、文档或图形等。它们不需要严格的模式定义和复杂的关系设计。
1.2 可扩展性:
关系型数据库:通常通过增加计算资源(例如,CPU、RAM或硬盘驱动器空间)来进行垂直扩展(scaling up)。然而,这种方法的缺点是成本较高并存在扩展限制。
垂直扩展(Vertical Scaling),也被称为“扩大”,是通过增加数据库服务器的硬件性能来提升数据库系统的处理能力。这通常意味着增加 CPUs,RAM 或 SSD 等资源。
具体来说,以下是垂直扩展可能包括的一些步骤:
- 增加 CPU 资源:可以提供更多的计算能力,使得数据库能够处理更复杂或者数量更大的任务。
- 增加内存 (RAM):有更多的数据可以在内存中快速访问,从而加快查询和其他数据库操作。
- 增加存储空间:可以容纳更多的数据和索引,从而支持大量的读写操作。
垂直扩展的优点包括:
- 实施简单,只需要对现有硬件进行升级。
- 数据一致性和完整性更易于维护,因为所有的数据都在一个地方。
- 然而,垂直扩展也有一些限制:
- 物理限制:每台服务器的硬件升级都有其极限。当达到这个极限时,就无法通过增加硬件资源来提高性能了。
- 价格问题:高性能的硬件成本往往非常高。
- 可用性问题:如果所有数据都在一台服务器上,那么这台服务器出现故障就会导致整个系统不可用。
非关系型数据库:更易于水平扩展(scaling out),即添加更多服务器到数据库中进行分区,以处理更大的数据量和交易负载。这种方式提供了更好的可扩展性,并且成本效益更高。
水平扩展,也被称为“扩大”,是通过添加更多的机器到你的资源池(如数据库服务器)以处理更多的负载的方法。这种方法通常涉及到分区或者数据分片,其中每个机器承担部分负载。
例如,在数据库的上下文中,水平扩展可能意味着增加更多的服务器来分散数据库查询的负载。通常情况下,数据库会被分解成多个分片,每个分片持有一部分整体数据,并且由单独的服务器托管。这样,查询可以在多个服务器上同时进行,从而提高了性能并减小了任何单台服务器的负载。
总的来说,水平扩展提供的是良好的可扩展性和容错性,但可能带来更复杂的数据管理和应用程序设计问题。
1.3 事务性
关系型数据库:支持ACID(原子性、一致性、隔离性和持久性)事务,在并发控制和回滚操作中都支持完整的事务管理,能够保证数据的正确性和完整性。
非关系型数据库:不是所有的NoSQL数据库都支持ACID事务。许多NoSQL数据库更倾向于实现 BASE(基本可用,软状态,最终一致)模型,牺牲一部分一致性以获得更高的可用性和可扩展性。
1.4 应用场景
关系型数据库:适合需要处理复杂事务和业务的场景,如银行系统、库存系统等。
非关系型数据库:适合需要处理海量数据并要求快速读写的场景,如社交网络、实时分析、推荐引擎等。
2 Redis优点
2.1 基于内存操作
内存读写速度快
2.2 支持多种数据类型
2.2.1 String
String的一个读写例子:
redis> SET mykey "Hello World"
OK
redis> GET mykey
"Hello World"
2.2.2 Hash
Redis 的哈希类型用于存储键值对的集合。以下是一个使用哈希类型数据操作的例子。 假设我们有一个名为 user1000
的哈希,它包含用户的基本信息。
- 设置哈希字段和值
HSET user1000 "name" "John Doe"
HSET user1000 "email" "john.doe@example.com"
HSET user1000 "password" "s3cret"
- 获取哈希的全部字段和值:
HGETALL user1000
返回值:
1) "name"
2) "John Doe"
3) "email"
4) "john.doe@example.com"
5) "password"
6) "s3cret"
- 获取特定字段的值:
HGET user1000 "name"
- 检查哈希中是否存在某个字段:
HEXISTS user1000 "email"
- 删除哈希中的某个字段:
HDEL user1000 "password"
- 获取哈希中的字段数量:
HLEN user1000
2.2.3 List
- 创建一个List:
lpush mylist "apple"
# (integer) 1
- 将更多元素添加到List中
lpush mylist "banana"
# (integer) 2
lpush mylist "cherry"
# (integer) 3
- 显示List的所有元素
lrange mylist 0 -1
# 1) "cherry"
# 2) "banana"
# 3) "apple"
- 删除List中的元素
lrem mylist 1 "banana"
# (integer) 1
https://www.nowcoder.com/discuss/500466833489666048?sourceSSR=search
1 redis的数据结构
Redis 支持多种数据结构,包括:
字符串(String): 这是最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。这个字符串类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。
哈希表(Hashes): Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
列表(Lists): Redis 列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。
集合(Sets): Redis set 是 string 类型的无序集合。也不允许重复的成员。
有序集合(Sorted sets): Redis sorted sets 和 set 一样也是 string 类型的集合,另外每个元素都会关联一个 double 类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
位图(Bitmaps): 位图其实就是字符串,但是对位提供了直接操作。通过bit命令,我们可以对字符串指定偏移量上的位(bit)直接进行操作。
HyperLogLogs: 这种数据结构主要用来统计唯一值,也就是用来做基数统计。
流(Streams): Redis Streams 是 Redis 5.0 引入的新特性,它是一个类似于日志系统的数据结构,支持存储多个键值对的时间戳,并且保持插入顺序。