PostgreSQL·国家地区表的设计
时间:2022-05-03
本文章向大家介绍PostgreSQL·国家地区表的设计,主要内容包括本文节选自《Netkiller Architect 手札》、4.22. PostgreSQL 所特有数据库设计、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
本文节选自《Netkiller Architect 手札》
4.22. PostgreSQL 所特有数据库设计
4.22.1. 国家地区表的设计
+-----------+
| city |
|-----------|
|id | <---+
|name | |
|description| 1:n
|status | |
|parent_id | o---+
+-----------+
例 4.2. 递归查询实例 city 表
定义结构
CREATE TABLE city
(
id serial NOT NULL,
name character varying,
parent_id integer,
status boolean,
CONSTRAINT city_pkey PRIMARY KEY (id),
CONSTRAINT city_parent_id_fkey FOREIGN KEY (parent_id)
REFERENCES city (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE city
OWNER TO sys;
插入数据
INSERT INTO city (id, name, parent_id, status) VALUES (1, '广东', NULL, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (2, '湖南', NULL, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (3, '深圳', 1, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (4, '东莞', 1, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (5, '福田', 3, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (6, '南山', 3, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (7, '宝安', 3, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (8, '西乡', 7, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (9, '福永', 7, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (10, '龙华', 7, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (11, '长沙', 2, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (12, '湘潭', 2, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (13, '常德', 2, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (14, '桃源', 13, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (15, '汉寿', 13, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (16, '黑龙江', NULL, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (17, '伊春', 16, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (18, '哈尔滨', 16, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (19, '齐齐哈尔', 16, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (20, '牡丹江', 16, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (21, '佳木斯', 16, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (22, '民治', 10, NULL);
INSERT INTO city (id, name, parent_id, status) VALUES (23, '上塘', 10, NULL);
查询
WITH RECURSIVE path(id, name, path, idpath, parent_id, status) AS (
SELECT id, name, '/' || name , '/' || id , parent_id, status FROM city WHERE parent_id is null
UNION
SELECT
city.id,
city.name,
parentpath.path ||
CASE parentpath.path
WHEN '/' THEN ''
ELSE '/'
END || city.name,
parentpath.idpath ||
CASE parentpath.idpath
WHEN '/' THEN ''
ELSE '/'
END || city.id,
city.parent_id, city.status
FROM city, path as parentpath
WHERE city.parent_id = parentpath.id
)
SELECT * FROM path;
结果输出
id | name | path | idpath | parent_id | status
----+----------+---------------------------+--------------+-----------+--------
1 | 广东 | /广东 | /1 | |
2 | 湖南 | /湖南 | /2 | |
16 | 黑龙江 | /黑龙江 | /16 | |
3 | 深圳 | /广东/深圳 | /1/3 | 1 |
4 | 东莞 | /广东/东莞 | /1/4 | 1 |
11 | 长沙 | /湖南/长沙 | /2/11 | 2 |
12 | 湘潭 | /湖南/湘潭 | /2/12 | 2 |
13 | 常德 | /湖南/常德 | /2/13 | 2 |
17 | 伊春 | /黑龙江/伊春 | /16/17 | 16 |
18 | 哈尔滨 | /黑龙江/哈尔滨 | /16/18 | 16 |
19 | 齐齐哈尔 | /黑龙江/齐齐哈尔 | /16/19 | 16 |
20 | 牡丹江 | /黑龙江/牡丹江 | /16/20 | 16 |
21 | 佳木斯 | /黑龙江/佳木斯 | /16/21 | 16 |
5 | 福田 | /广东/深圳/福田 | /1/3/5 | 3 |
6 | 南山 | /广东/深圳/南山 | /1/3/6 | 3 |
7 | 宝安 | /广东/深圳/宝安 | /1/3/7 | 3 |
14 | 桃源 | /湖南/常德/桃源 | /2/13/14 | 13 |
15 | 汉寿 | /湖南/常德/汉寿 | /2/13/15 | 13 |
8 | 西乡 | /广东/深圳/宝安/西乡 | /1/3/7/8 | 7 |
9 | 福永 | /广东/深圳/宝安/福永 | /1/3/7/9 | 7 |
10 | 龙华 | /广东/深圳/宝安/龙华 | /1/3/7/10 | 7 |
22 | 民治 | /广东/深圳/宝安/龙华/民治 | /1/3/7/10/22 | 10 |
23 | 上塘 | /广东/深圳/宝安/龙华/上塘 | /1/3/7/10/23 | 10 |
(23 rows)
- linux系统环境变量一文就够
- 百度搜索 “Java面试题” 前200页(面试必看)
- C# 给枚举类型增加一个备注特性
- 依赖注入(IOC)二
- Linux Token Auth 一次性密码认证
- WPF备忘录(7)WPF图片资源路径介绍
- 植入式攻击入侵检测解决方案
- 神经网络太臃肿?教你如何将神经网络减小四分之一
- WPF中ListView如何改变选中条背景颜色
- WPF Trigger for IsSelected in a DataTemplate for ListBox items
- C#基础知识回顾--BackgroundWorker介绍
- Elasticsearch 瞬间入门
- 使用OpenLDAP 操作 Windows Active Directory
- 优化算法:到底是数学还是代码?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 线程之生产者消费者模式
- Redis学习笔记 -- 2
- 一天一大 leet(单词拆分)难度:中等 DAY-25
- 多线程必考的「生产者 - 消费者」模型,看乔戈里这篇文章就够了
- 一天一大 leet(三角形最小路径和)难度:中等-Day20200715
- 一天一大 leet(将有序数组转换为二叉搜索树)难度:简单-Day20200703
- 一天一大 leet(缺失的第一个正数)难度:困难DAY-27
- 【玩转Redis面试第3讲】一次性将Redis RDB持久化和AOF持久化讲透
- 一天一大 leet(用两个栈实现队列)难度:简单 DAY-30
- SpringBoot实战:整合Redis、mybatis,封装RedisUtils工具类等(附源码)
- 时间序列&日期学习笔记大全(下)
- 带你了解鸿蒙开发基本流程
- Python 中也可以写 Excel 中的 “Vlookup” 函数?太牛逼了吧!
- 一天一大 leet(除数博弈)难度:简单-Day20200724
- 一天一大 leet(不同路径 II)难度:中等-Day20200706