Code:https://github.com/lotapp/BaseCode/tree/master/safehtml
本週須要自行研究學習的任務貼一下:前端
數據庫系列去年就開始陸陸續續的發文,這周任務簡單帶過,概念部分我更新了一下,其餘部分看擴展吧~mysql
引用百科的一段抽象
描述:git
「關係型數據庫,是指採用了關係模型來組織數據的數據庫,其以行和列的形式存儲數據,以便於用戶理解,關係型數據庫這一系列的行和列被稱爲表,一組表組成了數據庫。用戶經過查詢來檢索數據庫中的數據,而查詢是一個用於限定數據庫中某些區域的執行代碼。關係模型能夠簡單理解爲二維表格模型,而一個關係型數據庫就是由二維表及其之間的關係組成的一個數據組織。」github
通俗講就是:現實中的東西抽象成一個個關係,而後存儲在一張張行列組成的表中,這些表就組成了關係型數據庫面試
PS:重點就是各數據之間的
關係
(Join)redis
最經典的莫過於:MySQL
、SQLServer
、PostgreSQL
、SQLite
、Oracle
sql
先看看傳統數據庫的好處:數據庫
最典型的特徵就是:事物的ACID特性express
PS:抽象的就不說了,舉個例子來講明
ACID
:
化學反應不可再分的基本微粒
能量守恆
來理解國家互不干涉內政
交易留的底單
,這個就是持久化的表現保留字段
也容易由於預留名的不肯定性容易出錯主從複製
,讀數據在Salver
進行到沒啥事,可是大量寫數據庫懟到Master
上去就吃不消了,必須得加主數據庫了。數據不一致
(一樣數據在兩個主數據庫更新成不同的值),這時候得結合分庫分表,把表分散在不一樣的主數據庫中。擴充:如今對修改表結構是這麼的解決方案:
PS:雖然都是藉助工具來操做但原理仍是要了解下:
先建立新表,而後舊錶中建立一個觸發器(處理產生的新數據),而後把一條條數據轉移到新表中,接着刪除舊錶,更名新表
(和舊錶名同樣)
引用百科一段抽象
描述:
「非關係型數據庫,又被稱爲NoSQL(Not Only SQL ),主要是指非關係型、分佈式、不提供ACID的數據庫設計模式」
通俗化講就是:爲了彌補SQL的不足而建立的(能夠逆推NoSQL的優點)
PS:你能夠理解爲:NoSQL就是對原來SQL的擴展補充(
NewSQL
=SQL + NoSQL
)
先說說優點:
NoSQL的特性就是CAP
:
PS:CAP是分佈式系統須要考慮的三個指標,數據共享只能知足兩個而不可兼得:
表明:傳統關係型數據庫
若是想避免分區容錯性問題的發生,一種作法是將全部的數據(與事務相關的)都放在一臺機器上。雖然沒法100%保證系統不會出錯,但不會碰到由分區帶來的負面效果(會嚴重的影響系統的擴展性)
做爲一個分佈式系統,放棄P,即至關於放棄了分佈式,一旦併發性很高,單機服務根本不能承受壓力。像不少銀行服務,確確實實就是捨棄了P,只用高性能的單臺小型機保證服務可用性。(全部NoSQL數據庫都是假設P是存在的)
表明:Zookeeper
、Redis
(分佈式數據庫、分佈式鎖)
PS:NoSQL大部分都是CP
相對於放棄「分區容錯性」來講,其反面就是放棄可用性。一旦遇到分區容錯故障,那麼受到影響的服務須要等待數據一致
(等待數據一致性期間系統沒法對外提供服務)
表明:DNS數據庫
(IP和域名相互映射的分佈式數據庫
,聯想修改IP後爲何TTL
須要10分鐘左右保證全部解析生效)
放棄強一致,保證最終一致性。全部的NoSQL
數據庫都是介於CP
和AP
之間,儘可能往AP
靠
PS:傳統關係型數據庫注重數據一致性,而對NoSQL來講可用性和分區容錯性優先級高於數據一致性
不一樣數據對一致性要求是不同的,eg:
傳統關係型數據庫通常都是使用悲觀鎖的方式,可是例如秒殺這類的場景就玩不轉了,這時候每每就使用樂觀鎖了(CAS機制),CAP不能同時知足的時候也就剩下這兩個方案了:
分佈式事物來保證數據一致性
了(這就是問什麼項目裏面常常提到的緣由)Redis
的AOF
)經常使用的已經加粗:
LevelDB
和RocksDB
也是比較高效的解決方案pika
(redis的補充)能夠解決Redis容量過大的問題tinydb
sonic
很火RedisGraph
Dgraph
、Beam
PS:項目中最經常使用的其實就是Redis
、Elasticsearch
、MongoDB
最早接觸的是SQLServer,然後纔是MySQL系,下面我儘可能使用通用SQL
來講說傳統概念:
create、drop、alter
insert、delete、update、select
grant
(受權)、revoke
(回收)PS:CURD
(定義了用於處理數據的基本原子操做):建立(Create)更新(Update)讀取(Retrieve)刪除(Delete)操做
官方文檔:
以MariaDB
爲例,簡單列舉下經常使用類型:(傾體說明和MySQL
不同)
char()
:不區分字符大小寫類型的字符串,max:255個字符
varchar()
: 不區分字符大小寫類型的字符串
utf8編碼下最多支持21843個字符
)SQLServer
的nvarchar
text
:不區分字符大小寫的不限長字符串
單選值
多選值
MySQL系
獨有,SQLServer
沒有SQLServer
是bit
MySQL
的tinyint(1)
tinyint
:微小整型(1字節,8位)
[-2^7, 2^7)
(-128 ~ 127
)[0, 2^8)
(0 ~ 255
)0 ~ 65535
PS:SQLServer中沒這個類型
int
(4bytes,32bit)
[-2^31, 2^31)
,[-2147483648,2147483648)
[0, 2^32)
,[0,4294967296)
bigint
(8bytes,64bit)
[-2^63, 2^63)
[0, 2^64)
double
:雙精度浮點數(8字節)
SQLServer
的float
類型至關於MySQL
的double
decimal
:精確小數類型(比double更精確)
decimal(位數,小數點位數)
decimal(3,2)
=> x.xx
MySQL
同樣)
year(2)
:00~99(1bytes)
year(4)
:0000~9999(1bytes)
SQLServer沒有這個類型
datetime
:既有時間又有日期(8bytes)timestamp
:時間戳(4bytes)【精度更高】null
| not null
default xxx_value
primary key
unique key
unsigned
(MySQL系獨有)auto_increment
(通常只用於整型,MSSQL是identity
)
last_insert_id()
primary key(xx,...)
unique key(xx,...)
index index_name (xx,...)
PS:如今新版本數據庫兼容了SQLServer的nvarchar
寫法(執行成功後數據類型變成varchar
)【不推薦使用】
課後拓展:
MySQL:char、varchar、text的區別
create database [if not exists] db_name;
drop database [if exists] db_name;
create table [if not exists] tb_name(列名1,數據類型 修飾符,列名2,數據類型 修飾符);
drop table [if exists] db_name.tb_name;
alter table tb_name add 列名 數據類型 修飾符 [first | after 列名];
[first | after 列名]
alter table tb_name change 舊列名 新列名 類型 類型修飾符
alter table tb_name modify 列名 類型 類型修飾符
alter table tb_name alter 列名 set default df_value
alter table tb_name drop 字段名
create index index_name on tb_name(列名,...);
)
alter table tb_name add index [ix_name] (列名,...);
alter table tb_name add unique [uq_name] (列名,列名2...);
drop index index_name on tb_name
)
alter table tb_name drop index index_name;
alter table tb_name drop index uq_name;
通俗講:SQL_Mode就是設置SQL語法檢測的級別
MariaDB 5.x的SQLMode通常是空(沒什麼約束)
PS:
select version();
能夠查看DB的版本,select @@sql_mode;
能夠查看SQL_Mode的值
MySQL 5.7.27的SQLMode默認是:ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
簡單解析一下:
ONLY_FULL_GROUP_BY
:使用group by
時查詢的字段必須是group by
子句的列
select count(url),name from file_records group by url;
STRICT_TRANS_TABLES
:對全部支持事物類型的表作嚴格約束(線上版本通常都是這個)NO_ZERO_IN_DATE
和NO_ZERO_DATE
:防止0000-00-00
插入日期中ERROR_FOR_DIVISION_BY_ZERO
:分母爲0則報錯(默認是警告)NO_AUTO_CREATE_USER
:建立用戶的時候必須identified by 'pass'
來指定密碼
create user bryan@'%' identified by '含大小寫字母+數字的密碼';
NO_ENGINE_SUBSTITUTION
:建表的時候指定不可用存儲引擎會報錯PS:項目開發通常設置爲traditional
(使用傳統模型,不容許對非法值作插入操做),線上通常使用strict_trans_tables
來提升併發(阿里雲默認值)
以Ubuntu爲例:sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
(sql_mode='strict_trans_tables'
)
而後重啓mysql使配置生效:
sudo systemctl restart mysql
效果:
PS:從MySQL8開始,可經過set persist
命令將全局變量的修改持久化到(/var/lib/mysql/mysqld-auto.cnf
)配置文件中
eg:
set persist sql_mode='strict_trans_tables';
-- 若是存在就刪除數據庫 drop database if exists safe_db; -- 建立數據庫 create database if not exists safe_db;
-- 若是存在就刪除表 drop table if exists safe_db.users; -- mysql> help create table(低版本的默認值不支持函數) -- 建立表 create table users(字段名 類型 修飾符,...) create table if not exists safe_db.users ( id int unsigned auto_increment, -- 主鍵,自增加【獲取ID:last_insert_id()】 username varchar(20) not null, password char(40) not null, -- sha1:40 email varchar(50) not null, ucode char(36) not null, -- uuid createtime datetime not null default now(), updatetime datetime not null default now(), datastatus tinyint not null default 0, -- 默認值爲0 primary key (id), -- 主鍵可多列 unique uq_users_email (email), index ix_users_createtime_updatetime (createtime, updatetime) -- 索引,不指定名字默認就是字段名 ) -- 表選項 -- engine = 'innodb', -- 引擎 -- character set utf8, -- 字符集 -- collate utf8_general_ci, -- 排序規則 ;
-- 修改表 mysql> help alter table -- 3.1.添加一列 alter table tb_name add 列名 數據類型 修飾符 [first | after 列名] alter table safe_db.users add uid bigint not null unique first; -- MSSQL沒有[first | after 列名] -- 在email後面添加手機號碼列 -- 手機號不會用來作數學運算,varchar能夠模糊查詢(eg:like ‘138%’) -- 牽扯到國家代號時,可能出現+、-、()等字符,eg:+86 alter table safe_db.users add tel varchar(20) not null after email; -- 3.2.刪除一列 alter table tb_name drop 字段名 alter table safe_db.users drop uid; -- 3.3.添加索引 alter table tb_name add index [ix_name] (列名,...) alter table safe_db.users add index ix_users_ucode (ucode); -- 不指定名字默認就是字段名 -- add index (ucode, tel); -- 不指定索引名字,默認就是第一個字段名 -- 添加惟一鍵 alter table tb_name add unique [uq_name] (列名,列名2...) alter table safe_db.users add unique uq_users_tel_ucode (tel, ucode); -- add unique (tel, ucode);-- 不指定索引名字,默認就是第一個字段名 -- 3.4.刪除索引 alter table tb_name drop index ix_name alter table safe_db.users drop index ix_users_ucode; -- 刪除索引(惟一鍵) alter table tb_name drop index uq_name alter table safe_db.users drop index uq_users_tel_ucode; -- drop index tel; -- 惟一鍵的索引名就是第一個列名 -- 3.5.修改字段 -- 1.修改字段名:`alter table tb_name change 舊列名 新列名 類型 類型修飾符` -- 此時必定要從新指定該列的類型和修飾符 alter table safe_db.users change ucode usercode char(36); -- 2.修改字段類型 alter table safe_db.users modify username varchar(25) not null; -- 3.添加默認值:`alter table tb_name alter 列名 set default df_value` alter table safe_db.users alter password set default '7c4a8d09ca3762af61e59520943dc26494f8941b';
示例服務器:SQLServer 2014
use master --存在就刪除 if exists(select * from sysdatabases where Name = N'safe_db') begin drop database safe_db end --建立數據庫(簡化版:create database safe_db) create database safe_db on primary --數據庫文件,主文件組 ( name ='safe_db_Data', --邏輯名 size =10 mb, --初始大小 filegrowth =10%, --文件增加 maxsize =1024 mb, --最大值 filename =N'D:\Works\SQL\safe_db_data.mdf'--存放路徑(包含文件後綴名) ) log on --日記 ( name ='safe_db_Log', size =5 mb, filegrowth =5%, filename =N'D:\Works\SQL\safe_db_log.ldf' ); -- 切換數據庫 use safe_db;
--存在就刪除表 if exists(select * from sysobjects where name = N'users') begin drop table users end -- safe_db.dbo.users create table users ( id int identity, -- 主鍵,自增加 username nvarchar(20) not null, email varchar(50) not null, password char(40) not null, -- sha1 ucode char(36) not null default newid(), -- guid createtime datetime not null default getdate(), updatetime datetime not null default getdate(), datastatus tinyint not null default 0, -- 默認值爲0 primary key (id), -- 主鍵可多列 unique (email), index ix_users_createtime_updatetime (createtime, updatetime) -- 索引 );
-- 3.1.添加一列 alter table tb_name add 列名 數據類型 修飾符 -- 在email後面添加手機號碼列 alter table users add tel varchar(20) not null; -- 3.1.1.添加含惟一鍵的列 -- 先添加列 alter table users add uid bigint not null -- 再添加約束 alter table tb_name add constraint uq_name alter table users add constraint uq_users_uid unique (uid); -- 自定義名稱 -- 3.1.2.定義和約束一步走(系統設置名字) -- alter table users -- add uid bigint not null unique; -- 默認名稱 -- 3.2.含惟一鍵的列 -- 3.2.1.刪除約束 alter table tb_name drop constraint uq_name if exists(select * from sysobjects where name = 'uq_users_uid') alter table users drop constraint uq_users_uid; -- 3.2.2.刪除列 alter table tb_name drop column 字段名 alter table users drop column uid; -- 3.3.修改字段 -- 3.3.1.修改列名:exec sp_rename '表名.舊列名','新列名'; exec sp_rename 'users.ucode', 'usercode'; -- 3.3.2.修改字段類型 alter table users alter column username varchar(25) not null; -- 3.3.3.添加默認值:`alter table tb_name alter 列名 set default df_value` alter table users add default '7c4a8d09ca3762af61e59520943dc26494f8941b' for password;
PS:SQL Server默認端口爲TCP 1433
簡單列舉下上面的區別(歡迎補充):
auto_increment
,MSSQL是identity
unsigned
,MSSQL不能夠直接設置無符號整型,須要經過約束之類的來限制alter table
的時候,MSSQL沒有[first | after 列名]
,並且語法差異也挺大select語句執行流程:
from 表
[inner|left|right] join 表 on 條件
where 條件
group by 字段
分組
,以用作聚合
運算having 條件
group by
)後的結果進行過濾order by 字段 [asc|desc]
asc
)select 字段
limit [偏移量,]顯示數量
-- 4.1.插入 help insert -- 自增加主鍵和默認值的字段能夠不寫 insert into safe_db.users(username, password, email, tel, usercode, createtime, updatetime, datastatus) values ('test', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'test@qq.com', '18738002038', uuid(), now(), now(), 1); -- 批量插入 insert into safe_db.users(username, password, email, tel, usercode, createtime, updatetime, datastatus) values('xxx', '7c4a8d09ca3762af61e59520943dc26494f8942b', 'xxx@qq.com', '13738002038', uuid(), now(), now(), 0),('mmd', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'mmd@qq.com', '13718002038', uuid(), now(), now(), 1),('小張', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'zhang@qq.com', '13728002038', uuid(), now(), now(), 1); -- 4.2.修改 help update update safe_db.users set datastatus=99, updatetime = now() where username = 'mmd'; -- 必定要有where條件!開發中通常都是先寫where條件再寫update -- 4.3.刪除 -- 刪除數據(自增加不重置)help delete; delete from safe_db.users where datastatus = 0; -- 刪除所有數據(自增加重置)help truncate; truncate table safe_db.users;
file_records
的建表語句我放在附錄了,這邊只談語法
PS:查詢相關的幫助文檔:
help select
1.查詢來源url
use safe_db; -- 查詢來源url(去重後) select distinct url from file_records; -- 查詢來源url(分組方式) select url from file_records group by url;
2.統計url出現的次數
-- 分別統計一下url出現的次數(分組+聚合) -- 分組通常都和聚合函數一塊兒使用 select url, count(*) as count from file_records group by url; -- 分別統計一下url出現的次數大於1次的url(刪除的不統計) select url, count(*) as count from file_records where datastatus = 1 -- 99表明刪除的數據 group by url having count > 1; -- 在group by的結果上篩選
3.統計一下url出現的次數並查出對應的id
-- 分別統計一下url出現的次數並查出對應的id select group_concat(id) as ids, url from file_records group by url;
4.查詢上傳文件的用戶詳細信息,並按文件名降序排序
-- 內鏈接查詢 innet join tb_name on 關聯條件 select file_records.id, users.id as uid, users.username, users.email, file_records.file_name, file_records.md5, inet_ntoa(file_records.ip) as ip, file_records.url from users inner join file_records on file_records.user_id = users.id -- 鏈接條件 where users.datastatus = 1 and file_records.datastatus = 1 order by file_records.file_name desc; -- 文件名降序排序
5.查詢前五條文件上傳信息
-- MySQL沒有`select top n`語法,可使用 limit來實現,eg:top 5 select * from file_records limit 5; -- limit 0,5
6.分頁查詢相關
-- 分頁查詢 -- page:1,count=5 ==> 0,5 ==> (1-1)*5,5 -- page:2,count=5 ==> 5,5 ==> (2-1)*5,5 -- page:3,count=5 ==> 10,5 ==> (3-1)*5,5 -- 推理:limit (page-1)*count,count select file_records.id, users.id as uid, users.username, users.email, file_records.file_name, file_records.md5, inet_ntoa(file_records.ip) as ip, file_records.url from file_records inner join users on file_records.user_id = users.id limit 0,5; -- limit後面跟表達式就會報錯 select file_records.id, users.id as uid, users.username, users.email, file_records.file_name, file_records.md5, inet_ntoa(file_records.ip) as ip, file_records.url from file_records inner join users on file_records.user_id = users.id limit 5,5; -- limit (2-1)*5,5; -- limit錯誤寫法 -- limit要放在最後 select file_records.id, users.id as uid, users.username, users.email, file_records.file_name, file_records.md5, inet_ntoa(file_records.ip) as ip, file_records.url from file_records inner join users on file_records.user_id = users.id order by username desc, file_name desc limit 10,5; -- 先order by排完序,而後再取第三頁的5個數據
7.鏈接查詢
-- 查找一下歷來沒上傳過文件的用戶 -- right join:以右邊表(users)爲基準鏈接 select file_records.id as fid, users.id as uid, users.username, users.email, file_records.file_name, file_records.md5, inet_ntoa(file_records.ip) as ip, file_records.url from file_records right join users on file_records.user_id = users.id where users.datastatus = 1 and file_records.id is null order by username desc, file_name desc; -- 自鏈接案例: -- 二級聯動 p:province,c:city,a:area -- 前端通常都會顯示省級信息,用戶選擇後能夠得到對應的二三級信息 select c.name, a.name from city_infos as c inner join city_infos as a on a.pcode = c.code where c.pcode = '320000'; -- pcode設置爲索引 -- 經過省名稱查詢 select p.name, c.name, a.name from city_infos as c inner join city_infos as p on c.pcode = p.code inner join city_infos as a on a.pcode = c.code where p.name = '江蘇省';
-- 簡單提一下視圖: -- 建立視圖 create view view_userinfo as select id, username, password, email, tel, datastatus from safe_db.users; -- 查詢視圖 select id, username, password, email, tel, datastatus from safe_db.view_userinfo; -- 刪除視圖 drop view if exists view_userinfo;
知識點:
-- 把ip轉換成int select inet_aton('43.226.128.3'); -- inet6_aton() -- 把int轉換成ip select inet_ntoa('736264195'); -- inet6_ntoa() ipv6 -- 將多個字符串鏈接成一個字符串 select concat(user_id, ',', file_name, ',', ip, ',', url) as concat_str from file_records; -- 將多個字符串鏈接成一個字符串+能夠一次性指定分隔符 select concat_ws(',', user_id, file_name, ip, url) as concat_str from file_records; -- 在有group by的查詢語句中,select指定的字段要麼就包含在group by語句的後面,做爲分組的依據,要麼就包含在聚合函數中 -- group_concat():將group by產生的同一個分組中的值鏈接起來,返回一個字符串結果 select group_concat(file_name) as file_name, url, count(*) from file_records group by url; -- having通常對group by的結果進行篩選,where是對原表進行篩選 select group_concat(file_name) as file_name, group_concat(url) as url, count(*) as count from file_records group by url having count >= 3; -- 四捨五入到指定位數 select round(3.12345, 4); -- 存小數數據爲了避免損傷精讀通常都是轉成整數,eg:3.1415 ==> 整數:31415,倍數:10000
數據構造:
-- 編號,文件名,文件MD5,Meta(媒體類型),當前用戶,請求IP,來源地址,請求時間,數據狀態 drop table if exists safe_db.file_records; create table if not exists safe_db.file_records ( id int unsigned auto_increment primary key, file_name varchar(100) not null, md5 char(32) not null, meta_type tinyint unsigned not null default 1, user_id int unsigned not null, ip int unsigned not null, url varchar(200) not null default '/', createtime datetime not null, -- default now(), datastatus tinyint not null default 0 ); -- 能夠插入2~3次(方便下面演示) insert into safe_db.file_records(file_name, md5, meta_type, user_id, ip, url, createtime, datastatus) values ('2.zip', '3aa2db9c1c058f25ba577518b018ed5b', 2, 1, inet_aton('43.226.128.3'), 'http://baidu.com', now(), 1), ('3.rar', '6f401841afd127018dad402d17542b2c', 3, 3, inet_aton('43.224.12.3'), 'http://qq.com', now(), 1), ('7.jpg', 'fe5df232cafa4c4e0f1a0294418e5660', 4, 5, inet_aton('58.83.17.3'), 'http://360.cn', now(), 1), ('9.png', '7afbb1602613ec52b265d7a54ad27330', 5, 4, inet_aton('103.3.152.3'), 'http://cnblogs.com', now(), 1), ('1.gif', 'b5e9b4f86ce43ca65bd79c894c4a924c', 6, 3, inet_aton('114.28.0.3'), 'http://qq.com', now(), 1), ('大馬.jsp', 'abbed9dcc76a02f08539b4d852bd26ba', 9, 4, inet_aton('220.181.108.178'), 'http://baidu.com', now(), 99);
select語句執行流程:
from 表
join類型 join 表 on 條件
where 條件
group by 字段
分組
,以用作聚合
運算having 條件
group by
)後的結果進行過濾select distinct 字段
order by 字段 [asc|desc]
asc
)top 多少行
limit
-- 4.1.插入 help insert -- 自增加主鍵和默認值的字段能夠不寫 insert into safe_db.dbo.users(username, password, email, tel, usercode, createtime, updatetime, datastatus) values ('mmd', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'mmd@qq.com', '18738002038', newid(), getdate(), getdate(), 1); -- 批量插入 SQLServer一次批量插入最多1000行左右 insert into safe_db.dbo.users(username, password, email, tel, usercode, createtime, updatetime, datastatus) values ('xxx', '7c4a8d09ca3762af61e59520943dc26494f8942b', 'xxx@qq.com', '13738002038', newid(), getdate(), getdate(), 0), ('mmd', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'mmd@qq.com', '13738002038', newid(), getdate(), getdate(), 1), ('小明', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'xiaoming@qq.com', '13718002038', newid(), getdate(), getdate(), 1), ('小張', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'zhang@qq.com', '13728002038', newid(), getdate(), getdate(), 1), ('小潘', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'pan@qq.com', '13748002038', newid(), getdate(), getdate(), 1), ('小周', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'zhou@qq.com', '13758002038', newid(), getdate(), getdate(), 1), ('小羅', '7c4a8d09ca3762af61e59520943dc26494f8941b', 'luo@qq.com', '13768002038', newid(), getdate(), getdate(), 1); -- 4.2.修改 help update update safe_db.dbo.users set datastatus=99, updatetime = getdate() where username = 'mmd'; -- 必定要有where條件!開發中通常都是先寫where條件再寫update -- 4.3.刪除 -- 刪除數據(自增加不重置)help delete; delete from safe_db.dbo.users where datastatus = 0; -- 刪除所有數據(自增加重置)help truncate; truncate table safe_db.dbo.users;
-- 查詢來源url(去重後) select distinct url from file_records; -- 查詢來源url(分組方式) select url from file_records group by url; -- 分別統計一下url出現的次數(分組+聚合) -- 分組通常都和聚合函數一塊兒使用 select url, count(*) as count from file_records group by url; -- 分別統計一下url出現的次數,已經刪除的文件不算進去 select url, count(*) as count from file_records group by url having count(*) > 3; -- 在group by的結果上篩選,★寫成count就不行了★ -- 分別統計一下url出現的次數並查出對應的id -- SQLServer2017新增string_agg select ids =(select stuff((select ',' + cast(id as varchar(20)) from file_records as f where f.url = file_records.url for xml path ('')), 1, 1, '')),url from file_records group by url; -- 內鏈接查詢 innet join tb_name on 關聯條件 select file_records.id, users.id as uid, users.username, users.email, file_records.file_name, file_records.md5, file_records.ip, file_records.url from users inner join file_records on file_records.user_id = users.id -- 鏈接條件 where users.datastatus = 1 and file_records.datastatus = 1 order by file_records.file_name desc; -- 文件名降序排序 -- 顯示前5個數據 select top 5 * from file_records; -- 分頁查詢 第3頁,每頁5條 select * from (select row_number() over (order by username desc, file_name desc) as id, file_records.id as fid, users.id as uid, users.username, users.email, file_records.file_name, file_records.md5, file_records.ip, file_records.url from file_records inner join users on file_records.user_id = users.id) as temp where id > (3 - 1) * 5 and id <= 3 * 5; -- 簡單提一下視圖: -- 存在就刪除 if exists(select * from sysobjects where name = N'view_userinfo') begin drop view view_userinfo end -- 建立視圖 create view view_userinfo as select id, username, password, email, tel, datastatus from users; -- 查詢視圖 select id, username, password, email, tel, datastatus from view_userinfo;
知識點:
select getdate() as datatime, newid() as uuid; -- 相似於concat的效果 select cast(id as varchar(20)) + ',' from file_records for xml path (''); -- 移除多餘的字符 -- STUFF(<character_expression>,<開始>,<長度>,<character_expression>) -- 將字符串插入到另外一個字符串中。它會刪除開始位置第一個字符串中的指定長度的字符,而後將第二個字符串插入到開始位置的第一個字符串中 select stuff((select ',' + cast(id as varchar(20)) from file_records for xml path ('')), 1, 1, '');
數據構造:
--存在就刪除表 if exists(select * from sysobjects where name = N'file_records') begin drop table file_records end -- 由於SQLServer的int沒有unsigned,因此推薦使用bigint create table file_records ( id bigint identity (1,1) primary key, file_name varchar(100) not null, md5 char(32) not null, meta_type tinyint not null default 1, user_id int not null, ip bigint not null, -- 在程序中自行轉換 url varchar(200) not null default '/', createtime datetime not null default getdate(), datastatus tinyint not null default 0 ); -- 能夠插入3次(方便下面演示) insert into file_records(file_name, md5, meta_type, user_id, ip, url, createtime, datastatus) values ('2.zip', '3aa2db9c1c058f25ba577518b018ed5b', 2, 1, 736264195, 'http://baidu.com', getdate(), 1), ('3.rar', '6f401841afd127018dad402d17542b2c', 3, 3, 736103427, 'http://qq.com', getdate(), 1), ('7.jpg', 'fe5df232cafa4c4e0f1a0294418e5660', 4, 5, 978522371, 'http://360.cn', getdate(), 1), ('9.png', '7afbb1602613ec52b265d7a54ad27330', 5, 4, 1728288771, 'http://cnblogs.com', getdate(), 1), ('1.gif', 'b5e9b4f86ce43ca65bd79c894c4a924c', 6, 3, 1914437635, 'http://qq.com', getdate(), 1), ('大馬.jsp', 'abbed9dcc76a02f08539b4d852bd26ba', 9, 4, 3702877362, 'http://baidu.com', getdate(), 99);
聊聊數據庫~1.開篇(主要是NoSQL)
聊聊數據庫~2.SQL環境篇:
聊聊數據庫~3.SQL基礎篇:
聊聊數據庫~4.SQL優化篇:
聊聊數據庫~5.SQL運維上篇:
聊聊數據庫~6.SQL運維中篇:
CentOS7安裝MySQL8.0小計:
MySQL的SQL_Mode修改小計:http://www.javashuo.com/article/p-vmgtwffb-u.html
MySQL5.7.26 忘記Root密碼小計:
小計:協同辦公衍生出的需求:
IDE相關:JetBrains全家桶破解思路(最新更新:2019-08-01):
SQLServer性能優化之----強大的文件組----分盤存儲(水平分庫)
SQLServer性能優化之---水平分庫擴展:
SQLServer性能優化之---分表分庫技術(同義詞+連接服務器)
SQLServer性能優化之---數據庫級日記監控(XEVENT)
PS:逆天之前整理的SQLServer腳本:
https://github.com/lotapp/BaseCode/tree/master/database/SQL/SQLServer
我爲NET狂官方面試題-數據庫篇答案:
牛逼的OSQL----大數據導入:
數據庫更名系列(數據庫名,邏輯名,物理文件名)
SQLServer文件收縮-圖形化+命令:
數據庫分離附加(附日記丟失的處理)
數據庫備份相關:
利用SQLServer數據庫發送郵件:
【恢復掛起的解決方案】附加文件時候的提示「沒法從新生成日誌,緣由是數據庫關閉時存在打開的事務/用戶,該數據庫沒有檢查點或者該數據庫是隻讀的。」【數據庫恢復】