PostgreSQL 簡介
基于 C++開發(fā),免費(fèi)使用、修改、和分發(fā) PostgreSQL,不管是私用、商用、還是學(xué)術(shù)研究使用。
開始使用
Linux 下的安裝
第一步:安裝
運(yùn)行命令:sudo apt-get install postgresql -y
第二步:安全設(shè)置
安裝postgresql
之后系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè)空密碼的postgres
空密碼用戶,現(xiàn)在為她添加密碼
sudo passwd postgres
第三步:連接數(shù)據(jù)庫
psql postgres
第四步:查看幫助
postgres=# help
You are using psql, the command-line interface to PostgreSQL.
Type: \copyright for distribution terms
\h for help with SomethingQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
Mac 下的安裝
- 第一步:安裝
運(yùn)行命令:brew install postgresql
- 第二步:添加用戶,創(chuàng)建數(shù)據(jù)庫
createuser postgres
createdb -U postgres postgres
- 第三步:建立別名
alias pg.start='pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start'
alias pg.stop='pg_ctl -D /usr/local/var/postgres stop -s -m fast'
- 第四步:啟動(dòng)、連接數(shù)據(jù)庫
pg.start
psql postgres
- 第五步:查看幫助
postgres=# help
You are using psql, the command-line interface to PostgreSQL.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
pgAdmin3
一個(gè)設(shè)計(jì),維護(hù)和管理 Postgres 數(shù)據(jù)庫用的通用工具。
危險(xiǎn)!連接不成功要注意的地方
- 注意服務(wù)器的防火墻規(guī)則
- 修改服務(wù)器連接監(jiān)聽 (
postgersql.conf
配置文件 ) - 修改連接認(rèn)真方式 (
pg_hba.conf
配置文件 )
SQL 的組成
操作數(shù)據(jù)庫對(duì)象
沒有權(quán)限怎么辦?
必須使用超級(jí)管理員登陸才可以管理數(shù)據(jù)庫對(duì)象,默認(rèn)的 postgres 可能沒有建立數(shù)據(jù)庫權(quán)限。
使用 posgres 用戶登陸依然可以看到其他用戶的,找到你的超級(jí)用戶且用該賬戶登陸。
使用 pgAdmin 操作
新建操作
右鍵數(shù)據(jù)庫,就可以看見
新建數(shù)據(jù)庫
選項(xiàng)。
在面板上面,填好你要設(shè)置的內(nèi)容,點(diǎn)擊
SQL
選項(xiàng)卡,可以看到如下語句,這樣我們也同樣學(xué)習(xí)了語句。
CREATE DATABASE apple
WITH ENCODING='UTF8'
OWNER="Yugo"
CONNECTION LIMIT=-1;
COMMENT ON DATABASE apple
IS '這是我的 Blog 的數(shù)據(jù)庫';
編輯、刪除操作
這是已經(jīng)創(chuàng)建好的數(shù)據(jù)庫的基本屬性
(連接數(shù) -1 表示不限制)
,
- Create 腳本 (跟創(chuàng)建的時(shí)候 SQL 差不多,不過多了一些默認(rèn)選項(xiàng))
- 屬性 (編輯)
- 刪除/移除
修改了數(shù)據(jù)庫的基本屬性之后,還是會(huì)生成 SQL 語句
ALTER DATABASE apple
RENAME TO banana;
使用 SQL 語句操作
使用 pgAdmin 練習(xí) SQL
點(diǎn)擊該按鈕,彈出 SQL 編輯窗口
選擇你寫好的語句,點(diǎn)擊執(zhí)行按鈕
執(zhí)行成功后,將會(huì)給你相應(yīng)的反饋
使用終端進(jìn)行操作
Yugo=# \c
You are now connected to database "Yugo" as user "Yugo".
\c
查看我當(dāng)前用戶,和數(shù)據(jù)庫屬于的用戶
Yugo=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-------+----------+-------------+-------------+-------------------
Yugo | Yugo | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 |
banana | Yugo | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 |
db_milk | Yugo | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 |
postgres | Yugo | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 |
template0 | Yugo | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/Yugo +
| | | | | Yugo=CTc/Yugo
template1 | Yugo | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/Yugo +
| | | | | Yugo=CTc/Yugo
(6 rows)
\l
查看所有數(shù)據(jù)庫,相當(dāng)于show databases
Yugo=# \c banana
You are now connected to database "banana" as user "Yugo".
\c banana
切換到banana
數(shù)據(jù)庫 ,相當(dāng)于use banana
操作表
我們將通過 pgAdmin 的語句生成功能學(xué)習(xí)
創(chuàng)建表
banana=# create table users
banana-# (
banana(# id int primary key,
banana(# name varchar(25) not null,
banana(# email varchar(60) not null,
banana(# passwd varchar(255) not null);
CREATE TABLE
先創(chuàng)建一個(gè) users
表
banana=# \d
List of relations
Schema | Name | Type | Owner
--------+-------+-------+-------
public | users | table | Yugo
(1 row)
\d
顯示所有的表
banana=# \d users
Table "public.users"
Column | Type | Modifiers
--------+------------------------+-----------
id | integer | not null
name | character varying(25) | not null
email | character varying(60) | not null
passwd | character varying(255) | not null
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
\d users
顯示表 users
的具體內(nèi)容
可以看到在 pgAdmin 中已經(jīng)可以看到表,點(diǎn)擊生成腳本試一試
Create 腳本
CREATE TABLE public.users
(
id integer NOT NULL,
name character varying(25) NOT NULL,
email character varying(60) NOT NULL,
passwd character varying(255) NOT NULL,
CONSTRAINT users_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.users
OWNER TO "Yugo";
Select 腳本
SELECT id, name, email, passwd
FROM public.users;
Insert 腳本
INSERT INTO public.users(
id, name, email, passwd)
VALUES (?, ?, ?, ?);
Update 腳本
UPDATE public.users
SET id=?, name=?, email=?, passwd=?
WHERE <condition>;
Delete 腳本
DELETE FROM public.users
WHERE <condition>;
字段也可以顯示 Create 腳本
ALTER TABLE public.users ADD COLUMN name character varying(25);
ALTER TABLE public.users ALTER COLUMN name SET NOT NULL;
新建一個(gè)索引 命名為
Index
選擇字段為 id
CREATE INDEX "Index"
ON public.users (id ASC NULLS LAST)
自己再手寫一些腳本來當(dāng)做練習(xí)
create table student(
id int primary key,
name varchar(30) not null,
age numeric(3) not null,
classroom numeric(4) not null,
address varchar(40) not null
);
alter table student rename to person;
alter table person rename id to bh;
alter table person alter column name type varchar(50);
alter table person drop column classroom;
alter table person add column birthday date;
drop table if exists person;
數(shù)據(jù)類型
復(fù)習(xí)一下簡單的類型
整數(shù)類型
類型 | 范圍 |
---|---|
smallint | -32768 - 32767 |
int | -2147483648 - 2147483647 |
浮點(diǎn)類型
類型 | 范圍 |
---|---|
Real | 6位十進(jìn)制精度 |
Numeric(m,n) | 任意精度類型 |
來試一試這些類型吧
create table temp(
x smallint,
y int,
z real,
n numeric(5,3)
)
insert into temp values (2,3,2.55,6.213)
insert into temp values (2,3,2.55,44.412)
insert into temp values (2,3,2.55,44.4125) // 四舍五入
select * from temp;
時(shí)間與日期類型
類型名稱 | 含義 | 存儲(chǔ)需求 | 例子 |
---|---|---|---|
time | 只能用于一日內(nèi)的時(shí)間 | 8 byte | 10:02:03 |
date | 只能用于日期 | 4 byte | 1987-04-04 |
timestamp | 日期和時(shí)間 | 8 byte | 1987-04-04 10:05:05 |
動(dòng)手試一試
create table temp1(
t time,
d date,
tm timestamp
);
insert into temp1 values ('10:04:03','2013-04-23','2031-5-23 10:22:00');
select * from temp1;
字符串類型
類型名稱 | 說明 |
---|---|
char(n)/ character(n) | 固定長度字符串,不足補(bǔ)空白 |
varchar(n)/ character varying(n) | 變長字符串,有長度限制 |
Text | 變長字符串,無長度限制 |
動(dòng)手吧
create table temp3(
ch char(10),
vch varchar(30),
t text
);
insert into temp3 values('大表哥','大表哥1','大表哥2');
select * from temp3;
select concat('{',ch,'}'),concat('{',vch,'}'),concat('{',t,'}') from temp3;
可以看見ch
的后邊補(bǔ)了一些空白
選擇正確的數(shù)據(jù)類型
主要目的:優(yōu)化存儲(chǔ),提高數(shù)據(jù)庫性能
- 正確使用整數(shù)類型和浮點(diǎn)類型
- 日期與時(shí)間類型
- Char 與 Varchar 之間的特點(diǎn)與選擇(Char 自動(dòng)補(bǔ)齊空格,占的空間大,但是在搜索的時(shí)候快)
算數(shù)運(yùn)算符
- 加 +
- 減 -
- 乘 ×
- 除 /
- 求余、模運(yùn)算 %
自己跑一跑
select 3+2 , 3-2 , 4*3 , 5/2, 3%2;
比較運(yùn)算符
- Least 在倆個(gè)或者多個(gè)參數(shù)時(shí),返回最小值
- greatest 在倆個(gè)或者多個(gè)參數(shù)時(shí),返回最大值
- between and 判斷一個(gè)值是否落在倆個(gè)值之間
- in 判斷一個(gè)值是否是 in 列表中的任意一個(gè)值
- like 通配符匹配
自己跑一跑
select 1=0 , '2'=2, 'b'='b',null=null,null=1;
select 1=0 , '2'=2, 'b'='b',null=null,null=1;
select 'good'<>'god' , 1<>2, 2>1, 4!=4, 2>=1, 1>=1;
select 2 between 1 and 3, 2 between 3 and 5, 3 between 3 and 6 # 閉區(qū)間
select 2 in (2,3,4), 2 in (3,4,5), 2 not in (3,4,5);
select 'abc' like 'a%','abc' like '_b_','abc' not like '%d';
邏輯運(yùn)算符號(hào)
- AND
- OR
- NOT
試一試
select not '1', not 'y', not '0', not 'n';
select '1' and 'y' , '1' and '0' , '0' and 'n';
select '1' or 'y' , '1' or '0' , '0' or 'n';
視圖
SQL 里面的視圖,就像一個(gè)函數(shù),把一些語句放入這個(gè)函數(shù),減少非專業(yè)人士的查詢痛苦。
CREATE VIEW myview AS
SELECT city, temp_lo, temp_hi, prcp, date, location
FROM weather, cities
WHERE city = name;
SELECT * FROM myview;
外鍵
保證數(shù)據(jù)完整
city varchar(80) references cities(city)
事務(wù)
保證里面內(nèi)容,都完全完成
BEGIN;
UPDATE accounts SET balance = balance - 100.00
WHERE name = 'Alice';
......
COMMIT;
繼承
關(guān)鍵字inherits
,繼承人有被繼承的所有屬性,并且查詢也會(huì)有點(diǎn)不一樣。
CREATE TABLE cities (
name text,
population real,
altitude int -- (單位是英尺)
);
CREATE TABLE capitals ( -- (州首府)
state char(2)
) INHERITS (cities);
SELECT name, altitude
FROM cities
WHERE altitude > 500;
以上找出所有海拔超過 500 英尺的城市的名字, 包括州首府
SELECT name, altitude
FROM ONLY cities
WHERE altitude > 500;
以上找出所有不是州首府并且位于海拔大于或等于 500 英尺的城市
深入查詢
語法格式
select
{ * | <字段列表> }
from
[
<table_01>,<table_02>...
[whrere <expression>]
[group by <字段>] 分組
[having <expression>]
[order by <字段>] 排序
[limit [<offset>,]<row count>
]
練習(xí)
create table dept (
d_no int primary key,
d_name varchar(30),
d_location varchar(300)
);
insert into dept values (10,'運(yùn)維部門','美國西雅圖');
insert into dept values (20,'銷售部門','中光廣東');
insert into dept values (30,'測(cè)試部門','中國香港');
insert into dept values (40,'集成部門','中國北京');
insert into dept values (50,'財(cái)務(wù)部門','中國湖北');
insert into dept values (60,'開發(fā)部門','中國杭州');
create table employee (
e_no int primary key, -- 雇員編號(hào)
e_name varchar(30) not null,
e_gender char(2) not null,
dept_no int,
e_job varchar(50) not null,
e_salary numeric(9,2),
e_hireDate date,
constraint fk_tmp_deptno foreign key (dept_no) references dept(d_no)
);
insert into employee values (100,'趙志宇','f',10,'開發(fā)工程師',5000,'2010-01-01');
insert into employee values (101,'許啦啦','f',10,'開發(fā)工程師',6000,'2013-04-03');
insert into employee values (102,'龍飛機(jī)','f',10,'開發(fā)經(jīng)理',8000,'2008-01-01');
insert into employee values (103,'黃飛飛','m',20,'測(cè)試工程師',8000,'2009-01-02');
insert into employee values (104,'趙大炮','f',20,'測(cè)試工程師',6000,'2012-01-02');
insert into employee values (105,'趙飛機(jī)','f',20,'xiaoshou',5000,'2015-01-02');
insert into employee values (106,'吳龜龜','m',30,'xiaoshou',8000,'2014-01-02');
insert into employee values (107,'馮久久','f',30,'xiaoshou',6000,'2002-01-02');
insert into employee values (108,'譚迪迪','f',40,'chaiwu',7000,'2003-01-02');
insert into employee values (109,'廖餅餅','m',40,'chaiwu',6000,'2012-01-02');
insert into employee values (110,'吳大錘','f',null,'實(shí)習(xí)工程師',2000,'2011-01-02');
insert into employee values (111,'陳大大','f',null,'實(shí)習(xí)工程師',2000,'2010-01-02');
### select
存取的數(shù)據(jù)就是用來查的,所以說最基本的操作也是最重要的操作,查詢。
select * from dept;
select * from employee;
select e_no,e_name,e_hireDate from employee; -- 查詢部分字段
select e.e_no,e.e_name,e.e_hreDate from employee as e; -- 查詢部分字段,且為表設(shè)置別名
select e.e_no as a,e.e_name as b,e.e_hreDate as c from employee as e; -- 為字段顯示別名
select e_no,e_name,e_salary from employee where e_salary < 5000;
select e_no,e_name,e_gender from employee where e_gender = 'f';
select 2 in (2,3,4); -- true , 用于 where 中
select e_no,e_name,dept_no from employee where dept_no in (20,30);
select e_no,e_name,dept_no from employee where dept_no not in (20,30);
select 2 between 2 and 4; -- true , 2 in [2,4] 用于日期方便
select e_no,e_name,dept_no,e_hireDate from employee where e_hireDate between '2012-03-01' and '2015-01-01';
select 'abc' like 'a%';
select 'abc' like 'a__';
select e_no,e_name,e_job from employee where e_job like '實(shí)習(xí)%';
select e_no,e_name,dept_no from employee where dept_no is null;
select e_no,e_name,dept_no from employee where dept_no = null; -- error :null 跟任何值都不相等
select e_no,e_name,e_gender,dept_no from employee where e_gender = 'f' and dept_no = 10;
select e_no,e_name,e_gender,dept_no from employee where e_gender = 'f' and dept_no in (10,20);
select e_no,e_name,dept_no from employee where dept_no = 10 or dept_no = 20;
select e_no,e_name,e_salary from employee order by e_salary desc; -- Desc 降序 asc 升序(默認(rèn)) null 是最大值
select e_no,e_name,e_salary,e_hireDate from employee order by e_salary asc ,e_hireDate desc;
select e_no,e_name,e_salary,e_hireDate from employee order by e_salary asc ,e_hireDate desc nulls first; -- 這樣 null 顯示在前面 默認(rèn)是:nulls last
select * from employee limit 5;
select * from employee limit 5 offset 2; -- 從第二條開始 取五條
select e_no,e_name,e_job,d_no,d_name,d_location from employee,dept where dept_no = d_no; -- 空值不會(huì)顯示
select e_no,e_name,e_job,d_no,d_name,d_location from employee inner join dept on dept_no = d_no;
select e_no,e_name,e_job,d_no,d_name,d_location from employee left join dept on dept_no = d_no; -- 返回所有,空值無對(duì)應(yīng)照樣顯示空
select e_no,e_name,e_job,d_no,d_name,d_location from employee left outer join dept on dept_no = d_no; -- 左連接與左外連接相等
select e_no,e_name,e_job,d_no,d_name,d_location from employee left outer join dept on dept_no = d_no where dept_no = 10;
-- join type : inner/left/right
-- 子查詢 : exists 、 in 、標(biāo)量
select * from employee where exists
(select d_no from dept where d_name = '運(yùn)維部門' and d_no = dept_no);
select * from employee where not exists
(select d_no from dept where d_name = '運(yùn)維部門' and d_no = dept_no);
select * from employee where dept_no in
(select d_no from dept where d_name = '運(yùn)維部門');
-- || 代表字符串拼接
select e_no, e_name, (select d_name || ' ' || d_location
from dept where dept_no = d_no) as address from employee;
-- 結(jié)果集合并
select e_no,e_name,dept_no,e_salary from employee where dept_no in (10,20)
union all
select e_no,e_name,dept_no,e_salary from employee where e_salary > 5000;
-- 去掉重復(fù)的行
select e_no,e_name,dept_no,e_salary from employee where dept_no in (10,20)
union
select e_no,e_name,dept_no,e_salary from employee where e_salary > 5000;
-- 空值占位
select e_no,e_name,dept_no,e_salary,e_hireDate from employee where dept_no in (10,20)
union
select e_no,e_name,dept_no,e_salary,null from employee where e_salary > 5000;
函數(shù)
函數(shù)名稱 | 函數(shù)作用 |
---|---|
avg() | 某列的平均值 |
count() | 某列的行數(shù) |
max() | 某列最大值 |
min() | 某列最小值 |
sum() | 某列之和 |
length(s) | 計(jì)算字符串的長度 |
concate(s1,s2,s3...) | 字符串合并函數(shù) |
ltrim(s)/trim(s)/rtrim(s) | 去除空格函數(shù) |
replace(s,s1,s2) | 替換函數(shù) |
substring(s,n,len) | 獲取字串函數(shù) |
extract(type from d) | 獲取日期指定值函數(shù) |
current_date | 當(dāng)前日期 |
current_time | 當(dāng)前時(shí)間 |
now() | 當(dāng)前日期時(shí)間函數(shù) |
select e_no,e_name,e_hireDate, extract(year from e_hireDate),
extract(month from e_hireDate), extract(day from e_hireDate) from employee;
自定義函數(shù)
讓我們來看看基本語法吧
create function // 聲明創(chuàng)建函數(shù)
add(integer,integer) // 定義函數(shù)名稱,參數(shù)類型
returns integer // 定義函數(shù)返回值
as 'select $1 + $2;' // 定義函數(shù)體
language sql // 用以實(shí)現(xiàn)的函數(shù)語言的名稱
returns null on null input; // 定義參數(shù)為 Null 的時(shí)候的處理情況
create function add(integer,integer) returns integer
as 'select $1 + $2;'
language sql
returns null on null input;
select add(1,2);
-- or replace 假如數(shù)據(jù)庫中存在這個(gè)函數(shù)就替換掉
create or replace function concat_test(integer,varchar,date) returns varchar
as 'select $1||$2||$3;'
langugage sql
returns null on null input;
select e_no,e_name,e_hireDate,concat(e_no,e_name,e_hireDate),
concat_test(e_no,e_name,e_hireDate) from employee;
drop function concat_test(integer,varchar,date);
Index 索引
提高數(shù)據(jù)的查詢速度,加速表與表之間的連接
-- 默認(rèn)是 B-tree 索引
create index emp_name_index on employee(e_name);
drop index emp_name_index;
視圖
縮短語句的長度利器
create view v_emp_dev as select e_no , e_name ,e_salary , e_hireDate
from employee where dept_no = 10 order by e_salary desc;
select * from v_emp_dev;
drop view v_emp_dev;
其他作者的文章
- 8.x手冊(cè)
- bruce_wu 寫了PostgreSQL一個(gè)系列的讀書筆記
- Gtlions_Lai CentOS下的編譯安裝
Rust是Mozilla開發(fā)的注重安全、性能和并發(fā)性的編程語言。
歡迎來 rust-china 社區(qū) http://rust-lang-cn.org/ 逛逛。