15.2. Lesson: 实现数据模型

现在我们已经讨论了所有的理论,让我们创建一个新的数据库。这个数据库将被用来为后面的课程做练习。

The goal for this lesson: 安装所需的软件并使用它来实现我们的示例数据库。

15.2.1. 安装PostgreSQL

备注

您可以在https://www.postgresql.org/download/.上找到适用于您的操作系统的PostgreSQL包和安装说明请注意,文档将假设用户在Ubuntu下运行QGIS。

在Ubuntu下:

sudo apt install postgresql-9.1

您应该会收到这样的消息:

[sudo] password for qgis:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
postgresql-client-9.1 postgresql-client-common postgresql-common
Suggested packages:
oidentd ident-server postgresql-doc-9.1
The following NEW packages will be installed:
postgresql-9.1 postgresql-client-9.1 postgresql-client-common postgresql-common
0 upgraded, 4 newly installed, 0 to remove and 5 not upgraded.
Need to get 5,012kB of archives.
After this operation, 19.0MB of additional disk space will be used.
Do you want to continue [Y/n]?

新闻发布会 YEnter 并等待下载和安装完成。

15.2.2. 帮助

PostgreSQL有非常好的 online 文件。

15.2.3. 创建数据库用户

在Ubuntu下:

安装完成后,运行以下命令以成为postgres用户,然后创建一个新的数据库用户:

sudo su - postgres

出现提示时,输入您的正常登录密码(您需要具有sudo权限)。

现在,在postgres用户的bash提示符下,创建数据库用户。确保用户名与您的Unix登录名匹配:这将使您的工作更轻松,因为当您以该用户身份登录时,Postgres将自动验证您的身份:

createuser -d -E -i -l -P -r -s qgis

出现提示时,请输入密码。您应该使用与您的登录密码不同的密码。

这些选项意味着什么?

-d, --createdb     role can create new databases
-E, --encrypted    encrypt stored password
-i, --inherit      role inherits privileges of roles it is a member of (default)
-l, --login        role can login (default)
-P, --pwprompt     assign a password to new role
-r, --createrole   role can create new roles
-s, --superuser    role will be superuser

现在,您应该通过输入以下命令离开postgres用户的bashShell环境:

exit

15.2.4. 验证新帐户

psql -l

应该返回类似如下的内容::

Name      |  Owner   | Encoding | Collation  |   Ctype    |
----------+----------+----------+------------+------------+
postgres  | postgres | UTF8     | en_ZA.utf8 | en_ZA.utf8 |
template0 | postgres | UTF8     | en_ZA.utf8 | en_ZA.utf8 |
template1 | postgres | UTF8     | en_ZA.utf8 | en_ZA.utf8 |
(3 rows)

类型 Q 退场。

15.2.5. 创建一个数据库

这个 createdb 命令用于创建新数据库。它应该从bashShell提示符下运行:

createdb address -O qgis

您可以使用以下命令验证新数据库是否存在:

psql -l

它应该返回如下内容:

Name      |  Owner   | Encoding | Collation  |   Ctype    |   Access privileges
----------+----------+----------+------------+------------+-----------------------
address   | qgis     | UTF8     | en_ZA.utf8 | en_ZA.utf8 |
postgres  | postgres | UTF8     | en_ZA.utf8 | en_ZA.utf8 |
template0 | postgres | UTF8     | en_ZA.utf8 | en_ZA.utf8 | =c/postgres: postgres=CTc/postgres
template1 | postgres | UTF8     | en_ZA.utf8 | en_ZA.utf8 | =c/postgres: postgres=CTc/postgres
(4 rows)

类型 Q 退场。

15.2.6. 启动数据库Shell会话

您可以轻松地连接到数据库,如下所示:

psql address

要退出psql数据库Shell,请键入::

\q

有关使用Shell的帮助,请键入::

\?

有关使用SQL命令的帮助,请键入::

\help

要获取有关特定命令的帮助,请键入(例如):

\help create table

另请参阅 Psql cheat sheet

15.2.7. 在SQL中制作表格

让我们开始做一些桌子吧!我们将使用我们的ER图作为指导。首先,连接到地址db:

psql address

然后创建一个 streets 表:

create table streets (id serial not null primary key, name varchar(50));

serialvarchardata typesserial 通知PostgreSQL启动一个整数序列(自动编号)以填充 id 每一项新记录都会自动执行。 varchar(50) 通知PostgreSQL创建一个长度为50个字符的字符字段。

您会注意到该命令以一个 ; -所有的SQL命令都应该这样终止。当您按下 Enter ,psql将报告类似以下内容:

NOTICE:  CREATE TABLE will create implicit sequence "streets_id_seq"
         for serial column "streets.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index
         "streets_pkey" for table "streets"
CREATE TABLE

这意味着您的表已使用主键成功创建 streets_pkey 使用 streets.id

注意:如果按回车键时未输入 ; ,然后您将得到如下提示: address-# 。这是因为PG希望您输入更多内容。请输入 ; 来运行您的命令。

要查看您的表方案,您可以执行以下操作:

\d streets

它应该显示如下所示:

Table "public.streets"
Column  |         Type          |            Modifiers
--------+-----------------------+--------------------------------------
 id     | integer               | not null default
        |                       | nextval('streets_id_seq'::regclass)
 name   | character varying(50) |
Indexes:
  "streets_pkey" PRIMARY KEY, btree (id)

要查看表内容,您可以执行以下操作:

select * from streets;

它应该显示如下所示:

id | name
---+------
(0 rows)

如您所见,我们的桌子目前是空的。

Try Yourself 适度

使用上面显示的方法创建一个名为People的表:

添加电话号码、家庭住址、姓名等字段(这些不都是有效的名称:请更改它们以使其有效)。确保您为该表提供了一个数据类型与上面相同的ID列。

15.2.8. 在SQL中创建键

我们上面的解决方案的问题是,数据库不知道人和街道之间存在逻辑关系。要表达这种关系,我们必须定义一个指向Streets表的主键的外键。

../../../_images/er-people-streets.png

有两种方法可以做到这一点:

  • 在创建表之后添加密钥

  • 在创建表时定义键

我们的表已经创建好了,所以让我们以第一种方式来完成:

alter table people
  add constraint people_streets_fk foreign key (street_id) references streets(id);

这告诉我们 people 表,它的 street_id 字段必须与有效街道匹配 idstreets 桌子。

创建约束的更常见方法是在创建表时创建约束:

create table people (id serial not null primary key,
                     name varchar(50),
                     house_no int not null,
                     street_id int references streets(id) not null,
                     phone_no varchar null);

\d people

添加约束后,我们的表模式现在如下所示:

Table "public.people"

  Column   |         Type          |            Modifiers
-----------+-----------------------+---------------------------------
 id        | integer               | not null default
           |                       | nextval('people_id_seq'::regclass)
 name      | character varying(50) |
 house_no  | integer               | not null
 street_id | integer               | not null
 phone_no  | character varying     |
Indexes:
  "people_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
  "people_streets_fk" FOREIGN KEY (id) REFERENCES streets(id)

15.2.9. 在SQL中创建索引

我们想要对人名进行闪电般的快速搜索。为此,我们可以在People表的Name列上创建一个索引:

create index people_name_idx on people(name);

\d people

这将导致:

Table "public.people"

  Column   |         Type          |                      Modifiers
-----------+-----------------------+-----------------------------------
 id        | integer               | not null default nextval
           |                       | ('people_id_seq'::regclass)
 name      | character varying(50) |
 house_no  | integer               | not null
 street_id | integer               | not null
 phone_no  | character varying     |
Indexes:
 "people_pkey" PRIMARY KEY, btree (id)
 "people_name_idx" btree (name)    <-- new index added!
Foreign-key constraints:
 "people_streets_fk" FOREIGN KEY (id) REFERENCES streets(id)

15.2.10. 删除SQL中的表

如果您想要删除某个表,可以使用 drop 命令:

drop table streets;

在我们当前的示例中,上面的命令不起作用。为什么不行?

如果您使用相同的 drop table 上的命令 people 表,这将是成功的:

drop table people;

备注

如果您确实输入了该命令并删除了 people 表,现在是重建它的好时机,因为您将在下一个练习中使用它。

15.2.11. 浅谈pgAdmin III

我们将向您展示来自 psql 提示,因为这是学习数据库的一种非常有用的方式。然而,有更快、更容易的方法来完成我们向您展示的许多操作。安装pgAdmin III,您可以使用图形用户界面中的“指向并点击”操作来创建、删除、更改ETC表。

在Ubuntu下,可以这样安装:

sudo apt install pgadmin3

PgAdmin III将在另一个模块中详细介绍。

15.2.12. In Conclusion

现在您已经了解了如何完全从头开始创建一个全新的数据库。

15.2.13. What's Next?

接下来,您将学习如何使用DBMS添加新数据。