PostgreSQL入门,PostgreSQL和mysql

 

PostgreSQL被誉为“世界上功能最强大的开源数据库”,是以加州大学伯克利分校计算机系开发的POSTGRES 4.2为基础的对象关系型数据库管理系统。html

PostgreSQL支持大部分 SQL标准而且提供了许多其余现代特性:复杂查询、外键、触发器、视图、事务完整性、MVCC。一样,PostgreSQL 能够用许多方法扩展,好比,经过增长新的数据类型、函数、操做符、汇集函数、索引。linux

开发者能够无偿使用、修改和分发 PostgreSQL,无论是私用、商用、仍是学术研究使用。web

 

 

 

PostgreSQL:是以加州大学伯克利分校计算机系开发的 POSTGRES,如今已经改名为PostgreSQL,版本 4.2为基础的对象关系型数据库管理系统(ORDBMS)。PostgreSQL支持大部分 SQL标准而且提供了许多其余现代特性:复杂查询、外键、触发器、视图、事务完整性、MVCC。一样,PostgreSQL 能够用许多方法扩展,好比, 经过增长新的数据类型、函数、操做符、汇集函数、索引。无偿使用、修改、和分发 PostgreSQL,无论是私用、商用、仍是学术研究使用。sql

特色与优点:shell

PostgreSQL 是一个自由的对象-关系数据库服务器(数据库管理系统),它在灵活的 BSD-风格许可证下发行。它提供了相对其余开放源代码数据库系统(好比 MySQL 和 Firebird),和专有系统(好比 Oracle、Sybase、IBM 的 DB2 和 Microsoft SQL Server)以外的另外一种选择。
PostgreSQL 不寻常的名字致使一些读者停下来尝试拼读它,特别是那些把SQL拼读为"sequel"的人。PostgreSQL 开发者把它拼读为 "post-gress-Q-L"。它也常常被简略念为 "postgres"。
事实上, PostgreSQL 的特性覆盖了 SQL-2/SQL-92 和 SQL-3/SQL-99,首先,它包括了能够说是目前世界上最丰富的数据类型的支持,其中有些数据类型能够说连商业数据库都不具有, 好比 IP 类型和几何类型等;其次,PostgreSQL 是全功能的自由软件数据库,很长时间以来,PostgreSQL 是惟一支持事务、子查询、多版本并行控制系统(MVCC)、数据完整性检查等特性的惟一的一种自由软件的数据库管理系统。 Inprise 的 InterBase 以及SAP等厂商将其原先专有软件开放为自由软件以后才打破了这个惟一。最后,PostgreSQL拥有一支很是活跃的开发队伍,并且在许多黑客的努力下,PostgreSQL 的质量日益提升。数据库

从技术角度来说,PostgreSQL 采用的是比较经典的C/S(client/server)结构,也就是一个客户端对应一个服务器端守护进程的模式,这个守护进程分析客户端来的查询请求,生成规划树,进行数据检索并最终把结果格式化输出后返回给客户端。为了便于客户端的程序的编写,由数据库服务器提供了统一的客户端 C 接口。而不一样的客户端接口都是源自这个 C 接口,好比ODBC,JDBC,Python,Perl,Tcl,C/C++,ESQL等, 同时也要指出的是,PostgreSQL 对接口的支持也是很是丰富的,几乎支持全部类型的数据库客户端接口。这一点也能够说是 PostgreSQL 一大优势。编程

 

 

 


PostgreSQL入门教程

1、安装json

首先,安装PostgreSQL客户端。数组

sudo apt-get install postgresql-client
而后,安装PostgreSQL服务器。bash

sudo apt-get install postgresql
正常状况下,安装完成后,PostgreSQL服务器会自动在本机的5432端口开启。

若是还想安装图形管理界面,能够运行下面命令,可是本文不涉及这方面内容。

sudo apt-get install pgadmin3
2、添加新用户和新数据库

初次安装后,默认生成一个名为postgres的数据库和一个名为postgres的数据库用户。这里须要注意的是,同时还生成了一个名为postgres的Linux系统用户。

下面,咱们使用postgres用户,来生成其余用户和新数据库。好几种方法能够达到这个目的,这里介绍两种。

第一种方法,使用PostgreSQL控制台。

首先,新建一个Linux新用户,能够取你想要的名字,这里为dbuser。

sudo adduser dbuser
而后,切换到postgres用户。

sudo su - postgres
下一步,使用psql命令登陆PostgreSQL控制台。

psql
这时至关于系统用户postgres以同名数据库用户的身份,登陆数据库,这是不用输入密码的。若是一切正常,系统提示符会变为"postgres=#",表示这时已经进入了数据库控制台。如下的命令都在控制台内完成。

第一件事是使用password命令,为postgres用户设置一个密码。

password postgres
第二件事是建立数据库用户dbuser(刚才建立的是Linux系统用户),并设置密码。

CREATE USER dbuser WITH PASSWORD ';password';;
第三件事是建立用户数据库,这里为exampledb,并指定全部者为dbuser。

CREATE DATABASE exampledb OWNER dbuser;
第四件事是将exampledb数据库的全部权限都赋予dbuser,不然dbuser只能登陆控制台,没有任何数据库操做权限。

GRANT ALL PRIVILEGES ON DATABASE exampledb to dbuser;
最后,使用q命令退出控制台(也能够直接按ctrl+D)。

q
第二种方法,使用shell命令行。

添加新用户和新数据库,除了在PostgreSQL控制台内,还能够在shell命令行下完成。这是由于PostgreSQL提供了命令行程序createuser和createdb。仍是以新建用户dbuser和数据库exampledb为例。

首先,建立数据库用户dbuser,并指定其为超级用户。

sudo -u postgres createuser --superuser dbuser
而后,登陆数据库控制台,设置dbuser用户的密码,完成后退出控制台。

sudo -u postgres psql

password dbuser

q
接着,在shell命令行下,建立数据库exampledb,并指定全部者为dbuser。

sudo -u postgres createdb -O dbuser exampledb
3、登陆数据库

添加新用户和新数据库之后,就要以新用户的名义登陆数据库,这时使用的是psql命令。

psql -U dbuser -d exampledb -h 127.0.0.1 -p 5432
上面命令的参数含义以下:-U指定用户,-d指定数据库,-h指定服务器,-p指定端口。

输入上面命令之后,系统会提示输入dbuser用户的密码。输入正确,就能够登陆控制台了。

psql命令存在简写形式。若是当前Linux系统用户,同时也是PostgreSQL用户,则能够省略用户名(-U参数的部分)。举例来讲,个人Linux系统用户名为ruanyf,且PostgreSQL数据库存在同名用户,则我以ruanyf身份登陆Linux系统后,能够直接使用下面的命令登陆数据库,且不须要密码。

psql exampledb
此时,若是PostgreSQL内部还存在与当前系统用户同名的数据库,则连数据库名均可以省略。好比,假定存在一个叫作ruanyf的数据库,则直接键入psql就能够登陆该数据库。

psql
另外,若是要恢复外部数据,可使用下面的命令。

psql exampledb < exampledb.sql
4、控制台命令

除了前面已经用到的password命令(设置密码)和q命令(退出)之外,控制台还提供一系列其余命令。

h:查看SQL命令的解释,好比h select。
?:查看psql命令列表。
l:列出全部数据库。
c [database_name]:链接其余数据库。
d:列出当前数据库的全部表格。
d [table_name]:列出某一张表格的结构。
du:列出全部用户。
e:打开文本编辑器。
conninfo:列出当前数据库和链接的信息。
5、数据库操做

基本的数据库操做,就是使用通常的SQL语言。

建立新表

CREATE TABLE user_tbl(name VARCHAR(20), signup_date DATE);

插入数据

INSERT INTO user_tbl(name, signup_date) VALUES(';张三';, ';2013-12-22';);

选择记录

SELECT * FROM user_tbl;

更新数据

UPDATE user_tbl set name = ';李四'; WHERE name = ';张三';;

删除记录

DELETE FROM user_tbl WHERE name = ';李四'; ;

添加栏位

ALTER TABLE user_tbl ADD email VARCHAR(40);

更新结构

ALTER TABLE user_tbl ALTER COLUMN signup_date SET NOT NULL;

改名栏位

ALTER TABLE user_tbl RENAME COLUMN signup_date TO signup;

删除栏位

ALTER TABLE user_tbl DROP COLUMN email;

表格改名

ALTER TABLE user_tbl RENAME TO backup_tbl;

删除表格

DROP TABLE IF EXISTS backup_tbl;

 

 

 

 

 

 

 

 

架构基础
行话:pgsql使用了客户端/服务器模式。一个pgsql会话包含包含两个进程:
服务器进程。管理数据库文件,接收客户端程序的链接请求,表明客户端执行数据库操做。数据库服务器程序叫作postgres。客户端应用程序。进行数据库操做。客户端应用程序本质上能够很是多样化,一个客户端能够是一个面向文本的工具,一个图形界面应用程序,一个经过访问数据库来显示网页的web服务器,或者一个专门的数据库维护工具。有些是pgsql自带的,大部分是用户开发的。
客户端和服务器能够在不一样的主机上,经过TCP/IP链接通讯。记住这一点很重要,由于客户机上的文件再服务器上多是访问不到的,或者只能换个文件名访问。
pgsql服务器能够处理多并发的链接,它会为每一个链接fork一个新的进程。客户端和新的服务器进程的通讯与就服务器进程没有关系。主服务器进程会一直保持运行,等待客户端链接。

建立数据库
建立数据库能够检查你是否链接到了服务器。一个pgsql服务器能够管理不少数据库。
建立一个名为mydb的数据库:
$ createdb mydb
若是回车以后没有任何输出,说明建立数据库成功。你能够跳过本节了。

万一不幸出错了,这里给出了一些解决办法。
1. 找不到命令,错误以下:
createdb: command not found
说明pgsql的bin目录没有添加到环境变量。你能够选择将bin目录添加到环境变量,或者去bin目录下打开命令窗口,再或者使用绝对路径调用createdb命令。
$ /user/local/pgsql/bin/createdb mydb
建议添加仍是添加环境变量,一劳永逸。
2. 服务未启动,错误以下:
createdb: could not connect to database postgres: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
表示服务器未启动,至少是在createdb执行的时候还未启动。多试试吧,我也不知道该咋办。
3. 没有帐户,错误以下:
createdb: could not connect to database postgres: FATAL: role "joe" does not exist
这里joe是操做系统帐户,pgsql用户帐户与操做系统帐户不一样。你须要登陆Postgres帐户,建立一个用户帐户。也多是你被分配的pgsql帐户名与操做系统用户名不一样,这时,你可使用-U选项指定帐户或设置PGUSER环境变量来指定pgsql的用户名。
$ createdb -U user mydb
其中,user就是你的pgsql帐户名。
4. 权限不足,错误以下:
createdb: database creation failed: ERROR: permission denied to create database
这是你的帐户没有建立数据库的权限,你能够登陆管理员帐户进行修改。
pgsql容许建立任意数量的数据库。数据库名称必须以英文字母开头,且不超过63字节。
能够省略数据库名,建立与当前用户同名的数据库,以下:
$ createdb
删除数据库用dropdb命令:
$ dropdb mydb
dropdb命令必须指定数据库名称,即便是与用户名同名的数据库也必须指定,它不会默认用帐户名。它会删除与数据库相关联的全部文件,而且不能撤销,因此必定要三思而行。

访问数据库
有三种方式能够访问数据库:
pgsql终端,psql命令行工具;pgAdmin或支持ODBC或JDBC的office套件;编程语言API。
这里只介绍第一种方式,第二种方式不作介绍,第三种方式后面再说。
打开cmd(或PowerShell)命令行窗口,但愿你以前已经设置过环境 变量了。输入一下命令启动psql :
$ psql mydb
mydb就是以前建立的数据库。若是不指定数据库名称,默认会访问与当前帐户名同名的数据库。
回车后输入密码,你会获得以下输出:
​x psql (10.4)Type "help" for help.​mydb=>
mydb=>就是命令提示符,你能够输入SQL指令(以;结尾)或psql命令(以\开头)。
若是命令提示符是mydb=#,表示当前帐户是超级用户。
你能够输入如下几个命令试试:
mydb=> SELECT version();
mydb=> SELECT current_date;
mydb=> SELECT 2 + 2;
上面三个命令都是SQL命令,它们都以;结尾。
psql内部命令都以\开头。例如\h命令能够获取帮助,\q命令用来退出psql。
mydb=> \h
mydb=> \q

psql与cmd
pgsql安装后会默认安装两个工具,pgAdmin和SQL Shell(psql)。前者是图形界面工具,后者是命令行工具。
---------------------

 

 

 

 

 

2、添加新用户和新数据库

初次安装后,默认生成一个名为postgres的数据库和一个名为postgres的数据库用户。这里须要注意的是,同时还生成了一个名为postgres的Linux系统用户。

下面,咱们使用postgres用户,来生成其余用户和新数据库。好几种方法能够达到这个目的,这里介绍两种。

第一种方法,使用PostgreSQL控制台。

首先,新建一个Linux新用户,能够取你想要的名字,这里为dbuser。

sudo adduser dbuser

而后,切换到postgres用户。

sudo su - postgres

下一步,使用psql命令登陆PostgreSQL控制台。

psql

这时至关于系统用户postgres以同名数据库用户的身份,登陆数据库,这是不用输入密码的。若是一切正常,系统提示符会变为"postgres=#",表示这时已经进入了数据库控制台。如下的命令都在控制台内完成。

第一件事是使用\password命令,为postgres用户设置一个密码。

\password postgres

第二件事是建立数据库用户dbuser(刚才建立的是Linux系统用户),并设置密码。

CREATE USER dbuser WITH PASSWORD 'password';

第三件事是建立用户数据库,这里为exampledb,并指定全部者为dbuser。

CREATE DATABASE exampledb OWNER dbuser;

第四件事是将exampledb数据库的全部权限都赋予dbuser,不然dbuser只能登陆控制台,没有任何数据库操做权限。

GRANT ALL PRIVILEGES ON DATABASE exampledb to dbuser;

最后,使用\q命令退出控制台(也能够直接按ctrl+D)。

\q

第二种方法,使用shell命令行。

添加新用户和新数据库,除了在PostgreSQL控制台内,还能够在shell命令行下完成。这是由于PostgreSQL提供了命令行程序createuser和createdb。仍是以新建用户dbuser和数据库exampledb为例。

首先,建立数据库用户dbuser,并指定其为超级用户。

sudo -u postgres createuser --superuser dbuser

而后,登陆数据库控制台,设置dbuser用户的密码,完成后退出控制台。

sudo -u postgres psql

\password dbuser

\q

接着,在shell命令行下,建立数据库exampledb,并指定全部者为dbuser。

sudo -u postgres createdb -O dbuser exampledb

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

安装 PostgreSQL 10

下载 PostgreSQL 10,postgresql-10.1-3-linux-x64-binaries.tar.gz。下载地址:https://get.enterprisedb.com/postgresql/postgresql-10.1-3-linux-x64-binaries.tar.gz。

(注:安装脚本以下(须要有 /opt/local 写权限),可以使用以下命令建立 /opt/local 目录。)

1

2

sudo mkdir /opt/local

sudo chown -R $USER:$USER /opt/local

install_pg.sh

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

OPT_BASE=/opt

PGVERSION=10.1

PGBASE=$OPT_BASE/local/pgsql

PGHOME=$OPT_BASE/local/pgsql/$PGVERSION

PGDATA=$OPT_BASE/var/pgsql/$PGVERSION

PG_SOFT_¥TAR="postgresql-10.1-3-linux-x64-binaries.tar.gz"

if [ -d $PGHOME ]; then

rm -rf $PGHOME

elif [ ! -d $PGBASE ]; then

mkdir -p $PGBASE

fi

if [ ! -d $PGDATA ]; then

mkdir -p $PGDATA

fi

echo "Install PostgreSQL"

tar zxf $PG_SOFT_TAR -C $PGBASE

mv $PGBASE/pgsql $PGHOME

cp pg-pwfile $PGHOME

echo "Init PostgreSQL"

pushd $PGHOME

./bin/initdb --pgdata="$PGDATA" --auth=ident --auth-host=md5 --encoding=UTF-8 --locale=zh_CN.UTF-8 --username=postgres --pwfile=pg-pwfile

rm -f pg-pwfile

popd

cp pg_hba.conf $PGDATA

cp postgresql.conf $PGDATA

chmod 600 $PGDATA/*.conf

echo "Start PostgreSQL"

$PGHOME/bin/pg_ctl -D $PGDATA -l logfile start

sleep 5

#cp .pgpass ~/

$PGHOME/bin/psql -h localhost -U postgres -d postgres -f pg_init.sql

install_pg.sh 脚本安装时依赖文件的完整版压缩包在此下载:https://yangbajing.me/files/postgresql10-scripts.tar.gz

  • pg-pwfile:在初始化数据库时设置默认管理员帐户的密码

  • pg_hba.conf:默认只容许 127.0.0.1/8 访问数据库,这里改为容许全部网段可访问

  • postgresql.conf:修改数据库监听地址为 * ,监听全部本地网络地址

  • pg_init.sql:建立一个普通帐户 yangbajing 和测试用数据库 yangbajing ,密码也设置为 yangbajing

安装后PG数据库管理管理员帐号是 postgres,密码为 postgres。同时,还建立了一个普通帐号:yangbajing 和同名数据库 yangbajing,密码也是 yangbajing

将 /opt/local/pgsql/10.1/bin 目录加入系统环境变量。

1

2

echo 'export PATH="/opt/local/pgsql/10.1/bin:$PATH" >> ~/.bashrc

. ~/.bashrc

使用以下命令来启动或中止PostgreSQL 10数据库

启动数据库

1

pg_ctl -D /opt/local/var/pgsql/10.1 -l logfile start

中止数据库

1

pg_ctl -D /opt/local/var/pgsql/10.1 -l logfile stop

体验 PG

输入如下命令访问PG数据库:

1

psql -h localhost -U yangbajing -d yangbajing -W

根据提示输入密码登陆,进入 psql 的 REPL 界面。

1

2

3

4

5

Password for user yangbajing:

psql.bin (10.1)

Type "help" for help.

yangbajing=>

先创建一些测试表:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

CREATE TABLE t_role (

id         INT PRIMARY KEY,

name       VARCHAR(255) NOT NULL,

created_at TIMESTAMPTZ

);

CREATE TABLE t_user (

id         BIGSERIAL PRIMARY KEY,

name       VARCHAR(255) NOT NULL,

roles      INT []       NOT NULL,

data       JSONB,

created_at TIMESTAMPTZ

);

INSERT INTO t_role (id, name, created_at) VALUES (1, '超级管理员', now()), (2, '管理员', now()), (3, '用户', now());

INSERT INTO t_user(name, roles, data, created_at) VALUES

('root', '{1}', '{"email":"root@yangbajing.me"}', now()),

('羊八井', '{2,3}', '{"email":"yangbajing"}', now()),

('哈哈', '{3}', '{"email":"haha@yangbajing.me"}', now());

先来执行两个简单的 SELECT 查询:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

yangbajing=> select * from t_role;

id |    name    |          created_at

----+------------+-------------------------------

1 | 超级管理员 | 2018-02-01 22:03:17.168906+08

2 | 管理员     | 2018-02-01 22:03:17.168906+08

3 | 用户       | 2018-02-01 22:03:17.168906+08

(3 rows)

yangbajing=> select * from t_user;

id |  name  | roles |                 data                  |          created_at

----+--------+-------+---------------------------------------+-------------------------------

2 | root   | {1}   | {"email": "root@yangbajing.me"}       | 2018-02-01 22:06:21.140465+08

3 | 哈哈   | {3}   | {"email": "haha@yangbajing.me"}       | 2018-02-01 22:06:21.140465+08

1 | 羊八井 | {2,3}   | {"email": "yangbajing@yangbajing.me"} | 2018-02-01 22:04:41.580203+08

(3 rows)

接下来,尝试一些 PG 特点特性。

InsertOrUpdate

插入或更新,是一个颇有用的特性,当在主键冲突时能够选择更新数据。在PG中,是使用 ON CONFLICT 来实现这个特性的。

1

2

3

4

INSERT INTO t_role (id, name, created_at)

VALUES (3, '普通用户', now())

ON CONFLICT (id)

DO UPDATE SET name = EXCLUDED.name;

在经常使用的 INSERT 语句后面用 ON CONFLICT (...) DO .... 语句来指定在某个/些字段出现冲突时须要执行的语句。在 on CONFLICT (...) 里的参数须要是主键或惟一索引(能够为复合字段)。当冲突发生时则会执行 DO .... 后面的语句,这里咱们选择更新 name 字段的值。EXCLUDED 是用户引用在 VALUES .... 部分咱们将插入的数据,EXCLUDED.name 在这里就是 '普通用户' 。除 DO UPDATE,咱们还可使用 DO NOTHING 来简单的忽略插入时的主键冲突。

SERIAL/BIGSERIAL

看看表 t_user 的结构:

1

2

3

4

5

6

7

8

9

10

11

yangbajing=> \d t_user

Table "public.t_user"

Column   |           Type           | Collation | Nullable |              Default

------------+--------------------------+-----------+----------+------------------------------------

id         | bigint                   |           | not null | nextval('t_user_id_seq'::regclass)

name       | character varying(255)   |           | not null |

roles      | integer[]                |           | not null |

data       | jsonb                    |           |          |

created_at | timestamp with time zone |           |          |

Indexes:

"t_user_pkey" PRIMARY KEY, btree (id)

在建表时 id 字段的类型定义的是 BIGSERIAL ,但这里倒是显示的 bigint 类型;另外,还多了一个默认值:nextval('t_user_id_seq'::regclass) 。这是 PG 中的 序列 ,PG中使用序列来实现 自增值 的特性。

序列:t_user_id_seq

1

2

3

4

5

6

yangbajing=> \d t_user_id_seq

Sequence "public.t_user_id_seq"

Type  | Start | Minimum |       Maximum       | Increment | Cycles? | Cache

--------+-------+---------+---------------------+-----------+---------+-------

bigint |     1 |       1 | 9223372036854775807 |         1 | no      |     1

Owned by: public.t_user.id

也能够先建立序列,再设置字段的默认值为该序列的下一个值。

1

CREATE SEQUENCE t_user_id2_seq INCREMENT BY 1 MINVALUE 1 START WITH 1;

这里建立一个序列,设置最小值为1,从1开始按1进行递增。

数组类型

在建立 t_user 表的 roles 字段时,使用了数组类型 INT [] 。数组类型对于咱们的数据建模来讲颇有用,使用得好能够大大减小关系表的数量。

根据索引返回值

1

2

3

4

5

6

7

yangbajing=> SELECT id, name, roles[2], created_at FROM t_user;

id |  name  | roles |          created_at

----+--------+-------+-------------------------------

2 | root   |       | 2018-02-01 22:06:21.140465+08

3 | 哈哈   |       | 2018-02-01 22:06:21.140465+08

1 | 羊八井 |     1 | 2018-02-01 22:04:41.580203+08

(3 rows)

注意:PG 中,索引下标从0开始

以行的形式输出数组元素

1

2

3

4

5

6

7

8

yangbajing=> SELECT id, unnest(roles) AS role_id FROM t_user;

id | role_id

----+---------

2 |       1

3 |       3

1 |       2

1 |       1

(4 rows)

包含查找

1

2

3

4

5

yangbajing=> SELECT * FROM t_user WHERE roles @> ARRAY[1,2];

id |  name  | roles |                 data                  |          created_at

----+--------+-------+---------------------------------------+-------------------------------

1 | 羊八井 | {2,1} | {"email": "yangbajing@yangbajing.me"} | 2018-02-01 22:04:41.580203+08

(1 row)