数据库和数据表操作
本章将详细介绍PostgreSQL中数据库和数据表的创建、修改和删除操作,包括数据库的基本管理、数据表的定义、字段约束以及表结构的修改等内容。
2.1 数据库操作
创建数据库
在PostgreSQL中,可以使用CREATE DATABASE语句创建新的数据库:
-- 创建数据库
CREATE DATABASE mydb;
-- 创建数据库并指定编码和所有者
CREATE DATABASE mydb
WITH OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = 'zh_CN.UTF-8'
LC_CTYPE = 'zh_CN.UTF-8'
TEMPLATE = template0;
查看数据库
可以使用以下命令查看数据库列表:
-- 使用psql命令行工具
\l
-- 或者使用SQL查询
SELECT datname FROM pg_database;
切换数据库
在psql中切换到指定数据库:
\c mydb
删除数据库
使用DROP DATABASE语句删除数据库:
-- 删除数据库
DROP DATABASE mydb;
-- 如果数据库正在使用,可以强制删除(PostgreSQL 13+)
DROP DATABASE IF EXISTS mydb WITH (FORCE);
提示:删除数据库是不可逆操作,请谨慎使用。删除前请确保已备份重要数据。
2.2 数据表操作
创建数据表
使用CREATE TABLE语句创建数据表:
-- 创建简单表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
age INTEGER CHECK (age >= 0 AND age <= 150),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建带外键的表
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
product_name VARCHAR(255) NOT NULL,
quantity INTEGER DEFAULT 1,
price DECIMAL(10,2),
order_date DATE DEFAULT CURRENT_DATE
);
常用数据类型
数据类型 | 说明 | 示例 |
---|---|---|
INTEGER | 整数类型 | age INTEGER |
SERIAL | 自增整数 | id SERIAL |
VARCHAR(n) | 可变长度字符串 | name VARCHAR(100) |
TEXT | 文本类型 | description TEXT |
DECIMAL(p,s) | 精确数值类型 | price DECIMAL(10,2) |
DATE | 日期类型 | birth_date DATE |
TIMESTAMP | 日期时间类型 | created_at TIMESTAMP |
BOOLEAN | 布尔类型 | is_active BOOLEAN |
字段约束
PostgreSQL支持多种字段约束:
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL, -- 非空约束
sku VARCHAR(50) UNIQUE, -- 唯一约束
price DECIMAL(10,2) CHECK (price > 0), -- 检查约束
category_id INTEGER REFERENCES categories(id), -- 外键约束
description TEXT DEFAULT '暂无描述', -- 默认值约束
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
2.3 表结构修改
添加字段
-- 添加单个字段
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
-- 添加多个字段
ALTER TABLE users
ADD COLUMN address TEXT,
ADD COLUMN gender CHAR(1);
修改字段
-- 修改字段类型
ALTER TABLE users ALTER COLUMN phone TYPE VARCHAR(30);
-- 设置默认值
ALTER TABLE users ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP;
-- 删除默认值
ALTER TABLE users ALTER COLUMN created_at DROP DEFAULT;
重命名字段
ALTER TABLE users RENAME COLUMN phone TO telephone;
删除字段
ALTER TABLE users DROP COLUMN address;
重命名表
ALTER TABLE users RENAME TO customers;
2.4 查看表信息
查看表结构
-- 使用psql命令
\d users
-- 查看表定义
\d+ users
-- 使用SQL查询
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = 'users';
查看表约束
SELECT constraint_name, constraint_type
FROM information_schema.table_constraints
WHERE table_name = 'users';
2.5 删除数据表
删除表
-- 删除单个表
DROP TABLE users;
-- 删除多个表
DROP TABLE users, orders;
-- 如果表存在则删除
DROP TABLE IF EXISTS users;
级联删除
-- 删除表及其依赖对象
DROP TABLE users CASCADE;
提示:CASCADE选项会同时删除依赖于该表的对象(如视图、外键约束等),请谨慎使用。
2.6 实际应用示例
创建电商数据库示例
-- 创建数据库
CREATE DATABASE ecommerce;
-- 切换到新数据库
\c ecommerce;
-- 创建用户表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
first_name VARCHAR(50),
last_name VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建商品分类表
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建商品表
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL CHECK (price >= 0),
category_id INTEGER REFERENCES categories(id),
stock_quantity INTEGER DEFAULT 0 CHECK (stock_quantity >= 0),
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建订单表
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 创建订单项表
CREATE TABLE order_items (
id SERIAL PRIMARY KEY,
order_id INTEGER REFERENCES orders(id),
product_id INTEGER REFERENCES products(id),
quantity INTEGER NOT NULL CHECK (quantity > 0),
price DECIMAL(10,2) NOT NULL
);