SQL-学习-数据库入门/Ruby On Rails/待深入学习/root密码重设

1. 什么是数据库?

数据库的作用就是为了保存数据。
程序运行时的数据会放在内存之中,但是只要程序结束或关机就会消失了。需要永久保存数据的话,就会存放在硬盘上。我们在编程基础课程曾经学过,可以利用档案来将数据放在硬盘上。不过如果数据又多又杂,存成档案要怎么命名、档案要用什么格式才方便之后查询,这些都是问题。
数据库就是为了解决这些问题而发明了,除了可以保存大量数据,数据库还提供了方便的查询(Query)机制,以及提供 CRUD(Create, Read, Update, Delete) 操作.
关系型数据库
SQLite3 ; MySQL ; PostgreSQL ; Oracle ; MS SQL Server

2. 关系型数据库的特性一: Schema

在关系型数据库中,有一些共通的特性,第一个就是 Schema 纲要

《SQL-学习-数据库入门/Ruby On Rails/待深入学习/root密码重设》

例如在这张 Table,有 id、name、capacity、user_id 等字段,其中每一行(row)就一笔数据(data)。

《SQL-学习-数据库入门/Ruby On Rails/待深入学习/root密码重设》 execl表

在excel表中,每一格都可以随便你填什么,但是 Schema 纲要不一样。我们需要定义
数据型别(Data Type)。每个字段(Column)都要指定格式,只有符合格式才能存进数据库。不同数据库的数据类型大同小异,大体上都有:

字符串:varchar 或 text。varchar 默认是 255 字符、text 默认是 65535 字符。如果你要开一个字段来存长篇文章,text 可能会不够存,需要在额外指定长度。

数字: Integer, Decimal, Float

Blob 二进制: 可以存放档案。但是通常不建议把档案直接塞数据库,一来数据库塞太大不容易备份和管理、二来没有什么好处,因为你也没办法针对二进制档案进行条件搜寻和过滤。人们对于读档案也有心理准备会比较慢。所以通常只会在数据库里面纪录档案的 metadata 例如档名、大小、MimeType 等等,而实际的档案则放在档案系统上,或是上传到七牛或AWS S3等空间。

Boolean 布林

Date 日期

Time 时间

Datetime 日期时间

3. 关系型数据库的特性二: SQL 标准语法

关系型数据库都支援使用一种叫做 SQL (Structured Query Language) 的结构化查询语言。我们会用这种语法来操作数据库,例如:

INSERT INTO events VALUES ("RubyConf", 100);
#   这个 SQL 句会插入一笔数据到 events 表。

SELECT * FROM events;
#  这个 SQL 句告诉数据库拿出 events 表的所有数据。

4. 关系型数据库的特性三: ACID

关系型数据库的另一个重要的特性是 ACID,也就是Atomicity, Consistency, Isolation, Durability。在解释个别的意义前,我们先介绍一个关系型数据库的功能,叫做 Transaction 事务。
请想像这样的场景:当你再做银行转帐时,A 的馀额会减少、B 的馀额会增加,如果这是两个 SQL 操作的话,我们如何能保证这两个 SQL 操作必须是一起成功的?不能发生 A 钱变少了,但是 B 没有收到钱的情况。或是考虑一个更极端的场景,如果你和别人同时同一秒钟互相转帐,数据库会不会算错馀额?
要达成这种跨 Tables 多个 SQL 操作必须同时完成(或失败)的需求,就必须用上 Transaction 事务。语法是用BEGIN; 和 COMMIT; 把 SQL 句包裹在一起,例如:

BEGIN;
  INSERT INTO histories (user_id, amount) VALUES (1, -100);
  INSERT INTO histories (user_id, amount) VALUES (2, 100);
  UPDATE accounts SET balance=200 WHERE id=1;
  UPDATE accounts SET balance=300 WHERE id=2;
COMMIT;

每个 SQL 句必须用分号 ; 代表结束
这样 BEGIN; 和 COMMIT; 中间的所有 SQL 句,就会一起递交给数据库,要麻一起成功、要麻一起失败。

ACID

ACID 其实就是在说明 Transactin 的能耐,以下取自 wikipedia:

Atomicity 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
Consistency 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
Isolation 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
Durability 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
透过 Transactions 事务功能,关系型数据库可以在多人连线同时执行多个 SQL 句的情况下,也可以保证数据最后的正确性。

5. SQL 语言: DDL

关系型数据库使用 SQL(Structured Query Language) 语言,每个 SQL 句子叫做 SQL Query 或 SQL Statement。我们可以用 CLI 指令或 GUI 软件,用 SQL 语言对数据库进行查询和操作。
SQL 分成 DDL 和 DML 两种,都是用分号 ; 结尾。

Data Definition Language, DDL
如何告诉数据库去定义 Schema 纲要? 也是使用 SQL 语法,这类型的 SQL 就做 DDL(Data Definition Language)
建立、删除和更名数据库
每家方法不太一样,建议可以用 GUI 进行即可。PostgreSQL 和 MySQL 都是数据库服务器,可以管理很多不同数据库,例如你可以架很多 Rails 网站,但是只需要一个数据库服务器,里面建立不同数据库即可。
建立数据库时,请注意选择编码(Encoding)。PostgrSQL 可用 utf-8、MySQL 可用 utf8mb4 编码。
在 SQLite3 的话,直接在 Terminal 用 CLI 指令 sqlite3 your_db_name.db 就会打开(或产生)一个数据库档案。直接砍掉档案就是删除数据库。
以下用 SQLite3 示范。
建立 Table
以下 SQL 会建立events 表,并新增三个字段 name, capacity 和 date。默认是字段允许 NULL,除非加上 NOT NULL。

CREATE TABLE events (name VARCHAR(50) NOT NULL, capacity INTEGER, date DATE);

《SQL-学习-数据库入门/Ruby On Rails/待深入学习/root密码重设》

ALTER TABLE persons RENAME TO people;  # 改名 Table
ALTER TABLE people ADD COLUMN status VARCHAR(50);    # 新增字串
DROP TABLE IF EXISTS people;    # 删除table

**Migration 机制**
数据库 Schema 不是一成不变的,会随着软件变更升级也会有修改的需要。因此,在一些软件中会实作一种叫做 Migration 的功能,透过 Schema Migration 纪录目前的 schema 版本。开机的时候检查目前程式的版本和数据库里面的版本是否相同,不同的话,执行 Migration 更新 schema。这些 Migration 代码也会放进版本控制系统 Git 里面,这样整个团队的开发者和不同服务器上,都可以利用 Migration 来一致管理 Schame。这个功能就是大家熟习的 Rails Migration。
<hr>
### 6. SQL 语言: DML
操作数据的 SQL 就是 DML(Data Manipulation Language),也就是做 CRUD 的操作。

INSERT INTO events (capacity, name) VALUES (200, “JSConf”); # SQL 会新增数据
INSERT INTO events (capacity, name) VALUES (300, “COSCUP”), (300, “OSDC.TW”); # 插入多笔
SELECT * FROM events; # 查询全部events资料
SELECT name, capacity FROM events; # 查询指定资料
UPDATE events SET capacity=10; # 修改SQL 数据
DELETE FROM events; # 删除全部
DELETE FROM events WHERE name=”RubyConf”; # 只删除指定的

查有哪些 tables 和 columns
各家语法不一样:
SQLite3: .tables.schema tablename
MySQL: show tablesdescribe tablename
PostgreSQL: \dt\d tablename

7. 数据库规范化 Normalization

本质上就是 一对一,一对多,多对一(拆解成一对一与一对多)

8. 数据库设计实务

Primary Key 主键
所谓的 Primary Key 主键就是可以唯一识别的字段,在 Rails 中会默认产生一个字段是 id。

如何选择你的 Primary Key ?
最常见是自动递增的整数(Auto incrementing Primary Key),这是 Rails 的默认方式,也是大家熟悉的 ID
UUID 通用唯一识别码: 1. 分布式系统喜欢用 2. 或是当作 token URL 功能
Natural key (例如身分证号码, ISBN, 国码 ISO ALPHA-2) 等等,不过你需要真的确认不会重复,例如 ISBN 其实会重复的

Foreign Key (Reference Key) 外键
所谓的 Foreign Key 是指用来关联一对多的字段字段,例如上述 registrations 表中的 user_id 和 event_id。外键的命名没有特别规定,通常是 _id 结尾。
你不需要特别告诉数据库这个是 foreign key,就可以当他是 foreign key 来使用。

9. Joining

SQL 查询厉害的地方,就是可以同时关联(Joining)多张表来进行复杂的查询。让我们先准备示范用的数据。
以下是 user 一对多 events 的情境,请执行 sqlite3 demo2.db,并输入以下 SQL 建立 tables 和数据:

  CREATE TABLE events (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT, capacity INTEGER, user_id INTEGER);
  CREATE TABLE users (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT);
  INSERT INTO users (name) VALUES ('ihower');
  INSERT INTO users (name) VALUES ('john');
  INSERT INTO users (name) VALUES ('roy');
  INSERT INTO events (name, capacity, user_id) VALUES ('rubyconf',100, 1);
  INSERT INTO events (name, capacity, user_id) VALUES ('jsconf', 200, 1);
  INSERT INTO events (name, capacity, user_id) VALUES ('cssconf', 150, 2);
  INSERT INTO events (name, capacity, user_id) VALUES ('htmlconf', 300, NULL);

《SQL-学习-数据库入门/Ruby On Rails/待深入学习/root密码重设》

跨 Tables 进行 Joining 查询,常用的有 Inner Joining 和 Left Outer Joining 两种:

Inner joining 合并两张 tables,接不起来就不要:

捞出所有活动,以及该活动的主办人资料:

SELECT * FROM events INNER JOIN users ON events.user_id = users.id;
SELECT * FROM events, users WHERE events.user_id = users.id;

《SQL-学习-数据库入门/Ruby On Rails/待深入学习/root密码重设》

Outer joining 合并两张 tables,接不起就填 NULL:

捞出所有活动,以及该活动的主办人资料(包括没有主办人的活动):

SELECT * FROM events LEFT OUTER JOIN users ON events.user_id = users.id;

《SQL-学习-数据库入门/Ruby On Rails/待深入学习/root密码重设》

AS 语法

因为有多张 tables 在 SQL 时,column 最好必须加上 table name 当作 prefix (特别是有重复的 column name 时,在 WHERE 条件里可能会无法判断),而且可以加上别名 AS。

例如
SELECT events.id AS event_id, events.capacity AS ec, events.name FROM events INNER JOIN users ON events.user_id = users.id WHERE ec=100;

Joining 图表

《SQL-学习-数据库入门/Ruby On Rails/待深入学习/root密码重设》

《SQL-学习-数据库入门/Ruby On Rails/待深入学习/root密码重设》

10. Functions

计算 Aggregations
数量
SELECT COUNT(*) AS event_count FROM events;
为何要 Joining
回头想想看为什么需要 Joining 语法。SQL 的 Joining 语法是对新手比较困难的部分,没办法完全掌握是正常的。很多时候其实我们在 Rails 先将需要的数据通通捞出来,然后用 Ruby 进行过滤跟组合似乎也可以达成目标,为什么需要用到这些看起来很复杂的 SQL Joining 语法呢?
主要的原因还是查询速度和需要的内存空间,数据库是一套针对 SQL 优化非常快速的软件,因此可以用远比 Ruby 高效的方式来取出数据。更何况如果全部的数据都拿出来用 Ruby 处理,很可能内存也不够。例如以下的问题:请回答去年第三季所有商品的销售额,并根据分类计算总额。去年一整年的销售可能多达上百万笔,如果要逐笔捞出用 Ruby 处理,效能会非常低下。这时候就必须用 SQL 精准地捞出想要的数据才是可行的方式。

关系型数据库原理-最详讲解

涉及到基础的数据结构,算法,二叉树等,篇幅过长,难度较高,后期再补

Mac平台重新设置MySQL的root密码

您是否忘记了Mac OS 的MySQL的root密码? 通过以下4步就可重新设置新密码:

  1. 停止 mysql server. 通常是在 ‘系统偏好设置’ > MySQL > ‘Stop MySQL Server’
  1. 打开终端,输入:
 sudo /usr/local/mysql/bin/mysqld_safe --skip-grant-tables
  1. 打开另一个新终端,输入:
 sudo /usr/local/mysql/bin/mysql -u root       # 分四次输入


 UPDATE mysql.user SET authentication_string=PASSWORD('新密码') WHERE User='root';


 FLUSH PRIVILEGES;


 \q
  1. 重启MySQL.

*以上方法针对 MySQL V5.7.9, 旧版的mysql请使用:UPDATE mysql.user SET Password=PASSWORD('新密码') WHERE User='root';

有时候上述操作还会报错:ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

这就蛮奇怪的,因为刚刚我就是输入密码进去的,原因未知,好的,那我只好再设置:

mysql> SET PASSWORD = PASSWORD('123456');      # 123456 是重置的新密码

参考官方的文档

    原文作者:时间之友
    原文地址: https://www.jianshu.com/p/f9449c53478e
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞