PostgreSQL 簡介
基于 C++開發,免費使用、修改、和分發 PostgreSQL,不管是私用、商用、還是學術研究使用。
開始使用
Linux 下的安裝
第一步:安裝
運行命令:sudo apt-get install postgresql -y
第二步:安全設置
安裝postgresql
之后系統會自動創建一個空密碼的postgres
空密碼用戶,現在為她添加密碼
sudo passwd postgres
第三步:連接數據庫
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 下的安裝
- 第一步:安裝
運行命令:brew install postgresql
- 第二步:添加用戶,創建數據庫
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'
- 第四步:啟動、連接數據庫
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
一個設計,維護和管理 Postgres 數據庫用的通用工具。
危險!連接不成功要注意的地方
- 注意服務器的防火墻規則
- 修改服務器連接監聽 (
postgersql.conf
配置文件 ) - 修改連接認真方式 (
pg_hba.conf
配置文件 )
SQL 的組成
操作數據庫對象
沒有權限怎么辦?
必須使用超級管理員登陸才可以管理數據庫對象,默認的 postgres 可能沒有建立數據庫權限。
使用 posgres 用戶登陸依然可以看到其他用戶的,找到你的超級用戶且用該賬戶登陸。
使用 pgAdmin 操作
新建操作
右鍵數據庫,就可以看見
新建數據庫
選項。
在面板上面,填好你要設置的內容,點擊
SQL
選項卡,可以看到如下語句,這樣我們也同樣學習了語句。
CREATE DATABASE apple
WITH ENCODING='UTF8'
OWNER="Yugo"
CONNECTION LIMIT=-1;
COMMENT ON DATABASE apple
IS '這是我的 Blog 的數據庫';
編輯、刪除操作
這是已經創建好的數據庫的基本屬性
(連接數 -1 表示不限制)
,
- Create 腳本 (跟創建的時候 SQL 差不多,不過多了一些默認選項)
- 屬性 (編輯)
- 刪除/移除
修改了數據庫的基本屬性之后,還是會生成 SQL 語句
ALTER DATABASE apple
RENAME TO banana;
使用 SQL 語句操作
使用 pgAdmin 練習 SQL
點擊該按鈕,彈出 SQL 編輯窗口
選擇你寫好的語句,點擊執行按鈕
執行成功后,將會給你相應的反饋
使用終端進行操作
Yugo=# \c
You are now connected to database "Yugo" as user "Yugo".
\c
查看我當前用戶,和數據庫屬于的用戶
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
查看所有數據庫,相當于show databases
Yugo=# \c banana
You are now connected to database "banana" as user "Yugo".
\c banana
切換到banana
數據庫 ,相當于use banana
操作表
我們將通過 pgAdmin 的語句生成功能學習
創建表
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
先創建一個 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
的具體內容
可以看到在 pgAdmin 中已經可以看到表,點擊生成腳本試一試
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;
新建一個索引 命名為
Index
選擇字段為 id
CREATE INDEX "Index"
ON public.users (id ASC NULLS LAST)
自己再手寫一些腳本來當做練習
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;
數據類型
復習一下簡單的類型
整數類型
類型 | 范圍 |
---|---|
smallint | -32768 - 32767 |
int | -2147483648 - 2147483647 |
浮點類型
類型 | 范圍 |
---|---|
Real | 6位十進制精度 |
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;
時間與日期類型
類型名稱 | 含義 | 存儲需求 | 例子 |
---|---|---|---|
time | 只能用于一日內的時間 | 8 byte | 10:02:03 |
date | 只能用于日期 | 4 byte | 1987-04-04 |
timestamp | 日期和時間 | 8 byte | 1987-04-04 10:05:05 |
動手試一試
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) | 固定長度字符串,不足補空白 |
varchar(n)/ character varying(n) | 變長字符串,有長度限制 |
Text | 變長字符串,無長度限制 |
動手吧
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
的后邊補了一些空白
選擇正確的數據類型
主要目的:優化存儲,提高數據庫性能
- 正確使用整數類型和浮點類型
- 日期與時間類型
- Char 與 Varchar 之間的特點與選擇(Char 自動補齊空格,占的空間大,但是在搜索的時候快)
算數運算符
- 加 +
- 減 -
- 乘 ×
- 除 /
- 求余、模運算 %
自己跑一跑
select 3+2 , 3-2 , 4*3 , 5/2, 3%2;
比較運算符
- Least 在倆個或者多個參數時,返回最小值
- greatest 在倆個或者多個參數時,返回最大值
- between and 判斷一個值是否落在倆個值之間
- in 判斷一個值是否是 in 列表中的任意一個值
- 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 # 閉區間
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';
邏輯運算符號
- 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 里面的視圖,就像一個函數,把一些語句放入這個函數,減少非專業人士的查詢痛苦。
CREATE VIEW myview AS
SELECT city, temp_lo, temp_hi, prcp, date, location
FROM weather, cities
WHERE city = name;
SELECT * FROM myview;
外鍵
保證數據完整
city varchar(80) references cities(city)
事務
保證里面內容,都完全完成
BEGIN;
UPDATE accounts SET balance = balance - 100.00
WHERE name = 'Alice';
......
COMMIT;
繼承
關鍵字inherits
,繼承人有被繼承的所有屬性,并且查詢也會有點不一樣。
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>
]
練習
create table dept (
d_no int primary key,
d_name varchar(30),
d_location varchar(300)
);
insert into dept values (10,'運維部門','美國西雅圖');
insert into dept values (20,'銷售部門','中光廣東');
insert into dept values (30,'測試部門','中國香港');
insert into dept values (40,'集成部門','中國北京');
insert into dept values (50,'財務部門','中國湖北');
insert into dept values (60,'開發部門','中國杭州');
create table employee (
e_no int primary key, -- 雇員編號
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,'開發工程師',5000,'2010-01-01');
insert into employee values (101,'許啦啦','f',10,'開發工程師',6000,'2013-04-03');
insert into employee values (102,'龍飛機','f',10,'開發經理',8000,'2008-01-01');
insert into employee values (103,'黃飛飛','m',20,'測試工程師',8000,'2009-01-02');
insert into employee values (104,'趙大炮','f',20,'測試工程師',6000,'2012-01-02');
insert into employee values (105,'趙飛機','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,'實習工程師',2000,'2011-01-02');
insert into employee values (111,'陳大大','f',null,'實習工程師',2000,'2010-01-02');
### select
存取的數據就是用來查的,所以說最基本的操作也是最重要的操作,查詢。
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; -- 查詢部分字段,且為表設置別名
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 '實習%';
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 升序(默認) 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 顯示在前面 默認是: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; -- 空值不會顯示
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; -- 返回所有,空值無對應照樣顯示空
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 、標量
select * from employee where exists
(select d_no from dept where d_name = '運維部門' and d_no = dept_no);
select * from employee where not exists
(select d_no from dept where d_name = '運維部門' and d_no = dept_no);
select * from employee where dept_no in
(select d_no from dept where d_name = '運維部門');
-- || 代表字符串拼接
select e_no, e_name, (select d_name || ' ' || d_location
from dept where dept_no = d_no) as address from employee;
-- 結果集合并
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;
-- 去掉重復的行
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;
函數
函數名稱 | 函數作用 |
---|---|
avg() | 某列的平均值 |
count() | 某列的行數 |
max() | 某列最大值 |
min() | 某列最小值 |
sum() | 某列之和 |
length(s) | 計算字符串的長度 |
concate(s1,s2,s3...) | 字符串合并函數 |
ltrim(s)/trim(s)/rtrim(s) | 去除空格函數 |
replace(s,s1,s2) | 替換函數 |
substring(s,n,len) | 獲取字串函數 |
extract(type from d) | 獲取日期指定值函數 |
current_date | 當前日期 |
current_time | 當前時間 |
now() | 當前日期時間函數 |
select e_no,e_name,e_hireDate, extract(year from e_hireDate),
extract(month from e_hireDate), extract(day from e_hireDate) from employee;
自定義函數
讓我們來看看基本語法吧
create function // 聲明創建函數
add(integer,integer) // 定義函數名稱,參數類型
returns integer // 定義函數返回值
as 'select $1 + $2;' // 定義函數體
language sql // 用以實現的函數語言的名稱
returns null on null input; // 定義參數為 Null 的時候的處理情況
create function add(integer,integer) returns integer
as 'select $1 + $2;'
language sql
returns null on null input;
select add(1,2);
-- or replace 假如數據庫中存在這個函數就替換掉
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 索引
提高數據的查詢速度,加速表與表之間的連接
-- 默認是 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手冊
- bruce_wu 寫了PostgreSQL一個系列的讀書筆記
- Gtlions_Lai CentOS下的編譯安裝
Rust是Mozilla開發的注重安全、性能和并發性的編程語言。
歡迎來 rust-china 社區 http://rust-lang-cn.org/ 逛逛。