我们有一个团队为软件开发人员设计表格和关系。在我们的组织中,他们对执行 3NF 规范化非常严格——老实说,鉴于我们组织的规模以及需求或我们的客户如何随时间变化,我同意这一点。只有一个方面我不清楚他们设计决策背后的原因:地址。
虽然这主要集中在美国的地址,但我认为这适用于任何这样做的国家。地址的每一部分在地址表中都有自己的列。例如,以这个粗糙的美国地址为例:
Attn: Jane Doe
485 1/2 N Smith St SW, APT 300B
Chicago, IL 11111-2222
Run Code Online (Sandbox Code Playgroud)
它会像这样在数据库中拆分:
还会有一些其他与农村路线和合同路线相关的专栏。此外,我们的特定应用程序中可能会包含一些国际地址。数据建模人员表示,他们将添加特定于国际地址的列,这将是正常的第 1 行、第 2 行字段。
起初我认为这太过分了。在网上反复搜索是指使用地址行 1、2、3 和可能的 4,然后拆分出城市、地区和邮政编码。我们的新应用程序确实有一个用例,这种粒度是有益的。我们必须验证用户没有创建重复的业务,检查地址是验证之一。我们可以让它与地址行 1 和 2 一起工作,但这会更困难。
至于我们的具体应用,我们需要为企业和个人存储多种地址(物理、邮寄、运输等)。我们可能需要生成可打印的套用信函,但目前尚未讨论该要求。
我们组织中的应用程序需要支持的其他一些东西:
虽然我们的应用程序可能不会做所有其他应用程序正在做的所有事情,但将地址拆分为多个组件是我工作的企业标准。不管我们的应用程序是否会从中受益,我们都被迫这样做。
半相关的 StackOverflow 问题:关闭的好的地址解析器在哪里,但说明解析地址有多么困难。
为了让我更好地理解他们的设计决策,并把这个想法卖给我们的客户……
将街道地址拆分为单独的列解决了哪些问题?
任何实施过此类系统的人都会获得奖励积分,因为他们遇到了问题。
我刚刚在我的笔记本电脑上创建了一个 PostgreSQL 数据库(按照这些说明),它运行的是 Linux CentOS 7。
现在我想了解我的默认数据库的主机名地址是什么。我以为是,localhost
但不是。
我想知道要与psql -h
命令一起使用的名称或 IP 地址。基本上,运行此psql -h HOSTNAME
命令应该让我psql
单独获得与该命令相同的结果,即让我连接到我的数据库。
我的默认数据库的主机名地址是什么?
Run Code Online (Sandbox Code Playgroud)> service postgresql status
状态:
? postgresql.service - PostgreSQL 数据库服务器已加载:已加载(/usr/lib/systemd/system/postgresql.service;已启用;供应商预设:已禁用)活动:自 2017 年 3 月 30 日星期四 14:40:30 EDT 起处于活动状态(正在运行) ; 1 天 1 小时前主 PID: 2256 (postgres
而两者psql -h 127.0.0.1
并psql -h 127.0.0.1 -U davide
产生此消息:
psql:致命:用户“david”的身份验证失败`
例如,假设我想为 Chicken Ranch 解析这些地址
Chicken Ranch
10511 Homestead Rd
Pahrump, NV 89061
Chicken Ranch
1600 Pennsylvania Avenue
NW Washington, D.C. 20500
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,我都想摆脱Rd
和Avenue
。例如,在第一种情况下,我想获得“Homestead”,而在第二个“Pennsylvania”中。不过,并非每个地址都有这样的名称。
我们正在为功能有限的社交网络应用程序设计数据库。用户(注册用户)、零售店等是我们需要存储的几个实体。我们需要存储每个实体的地址。我们还需要存储注册用户、零售店等的纬度和经度。
最初我们设计了如下所示的表格。我们创建了一个单独的地址表,因为用户、零售店和其他实体的地址格式相同。
User(UserID, UserName, AddressID)
RetailOutlet(RetailOutletID, OutletName, AddressID)
Address(AddressID, CityID, AddressLine1, AddressLine2, Latitude, Longitude)
Run Code Online (Sandbox Code Playgroud)
现在我们意识到我们需要搜索靠近用户当前位置(CurrentLatitude,CurrentLongitude)的零售店,所以我们需要运行一个查询,如
SELECT OutletName
from RetaileOutlet
INNER JOIN Address ON RetailOutlet.AddressID = Address.AddressId
WHERE Address.Latitude BETWEEN CurrentLatitude - 10 and CurrentLatitude + 10 and
Address.Longitude BETWEEN CurrentLongitude - 10 and CurrentLongitude + 10
Run Code Online (Sandbox Code Playgroud)
现在我们认为上面的查询会运行缓慢,因为用户数量将远远超过零售店数量。从数据库设计/性能的角度来看,应该完成以下哪一项。
在 Address 表中的 Latitude、Longitude 和 RetailOutlet 表中的 AddressID 上创建索引。所以表结构不会发生变化。
将纬度、经度从地址表移动到零售店和用户表。还要在 RetailOutlet 表中的纬度、经度上创建索引。所以表结构如下所示。
User(UserID, UserName, AddressID, Latitude, Longitude)
RetailOutlet(RetailOutletID, OutletName, AddressID, Latitude, Longitude)
Address(AddressID, CityID, AddressLine1, AddressLine2)
Run Code Online (Sandbox Code Playgroud)如下所示更改表结构,并在 UserAddress 表中的 Lat、Lng 和 User 表中的 …
要求:用户可以将单个 ips 或 ip 地址范围添加到数据库表(例如具有 ipAddressesinet[]
类型的权限表)。我需要查询单个 ip 是否包含在 ipAddresses 字段数组中,该数组可以是 ip 地址数组或 ip 地址范围数组,也可以是两者。我试图添加这样的查询:
WHERE "ipAddresses" @> '192.168.1.5'::inet
Run Code Online (Sandbox Code Playgroud)
也喜欢这个
WHERE "ipAddresses" >> '192.168.1.5'::inet
Run Code Online (Sandbox Code Playgroud)
但没有运气。提前致谢。
id uuid NOT NULL gen_random_uuid()
permissions uuid[]
ipAddresses inet[]
createdAt timestamp with time zone now()
updatedAt timestamp with time zone now()
Run Code Online (Sandbox Code Playgroud)
当我四处搜索时,推荐的方法是使用同一个表中的发票地址和送货地址,并使用“类型”字段来显示它是什么。例如
Addresses(Company, address, city, type)
Run Code Online (Sandbox Code Playgroud)
Type = 1:地址是收货地址
Type = 2:地址为发票地址
Type = 3:收货地址和发票地址(地址相同)
如果有人不看我使用数据库的代码,他们就不会知道类型 2 是什么。是交货、发票还是两者兼而有之?你通常会澄清这一点吗?如何澄清?例如,如果有人想在数据库(在调用数据库的代码之外)搜索所有账单地址,他们不知道是否应该使用类型 1、2 或 3 从数据库客户端获取所有发票地址。
与如果您有两张桌子相比,那么桌子的名称说明它是什么,任何人都可以轻松挑选出所有发票地址。
Delivery(Company, address, city)
Invoice(Company, address, city)
Run Code Online (Sandbox Code Playgroud)