数据库管理员

希望提高数据库技能并向社区中的其他人学习的数据库专业人员的问答

1
PostgreSQL中的(x IS NOT NULL)与(NOT x IS NULL)
为什么x IS NOT NULL不等于NOT x IS NULL? 这段代码: CREATE TABLE bug_test ( id int, name text ); INSERT INTO bug_test VALUES (1, NULL); DO $$ DECLARE v_bug_test bug_test; BEGIN RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NULL); RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NOT NULL); RAISE NOTICE '%: %', …
16 postgresql  null 

3
在IF EXISTS中包装查询会使它非常慢
我有以下查询: select databasename from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt' and not exists(select 1 from dbo.smalltable c where c.source=l.source) 上面的查询将在三秒钟内完成。 如果上面的查询返回任何值,我们希望存储过程为EXIT,因此我将其重写如下: If Exists( select databasename from somedb.dbo.bigtable l where databasename ='someval' and source <>'kt' and not exists(select 1 from dbo.smalltable c where c.source=l.source) ) Begin Raiserror('Source missing',16,1) Return …

2
CREATE TABLE AS与SELECT INTO
PostgreSQL支持CREATE TABLE AS,SELECT INTO何时同时使用两者? CREATE TABLE AS -根据查询结果定义新表 CREATE TABLE AS创建一个表,并用SELECT命令计算的数据填充该表。表列具有与的输出列关联的名称和数据类型SELECT(除非您可以通过提供新列名称的显式列表来覆盖列名称)。 CREATE TABLE AS与创建视图有些相似,但实际上是完全不同的:它创建一个新表并仅对查询进行一次评估以最初填充新表。新表将不会跟踪对查询源表的后续更改。相反,SELECT无论何时查询,视图都会重新评估其定义语句。 接着。 SELECT INTO -根据查询结果定义新表 SELECT INTO创建一个新表并将其填充查询所计算的数据。数据不会像常规一样返回给客户端SELECT。新表的列具有与的输出列关联的名称和数据类型SELECT。
16 postgresql  ctas 

2
SQL Server用与定义不匹配的数据填充PERSISTED列是否合法?
我正在跟踪有关计算列中的奇怪值的问题PERSISTED。那里的答案使人对这种行为的产生方式有一些猜测。 我在问以下问题:这不是一个彻底的错误吗?是否PERSISTED允许列以这种方式运行? DECLARE @test TABLE ( Col1 INT, Contains2 AS CASE WHEN 2 IN (Col1) THEN 1 ELSE 0 END PERSISTED) --depends on Col1 INSERT INTO @test (Col1) VALUES (ABS(CHECKSUM(NEWID()) % 5)), (ABS(CHECKSUM(NEWID()) % 5)), (ABS(CHECKSUM(NEWID()) % 5)), (ABS(CHECKSUM(NEWID()) % 5)), (ABS(CHECKSUM(NEWID()) % 5)) SELECT * FROM @test --shows impossible …

2
非整数主键注意事项
语境 我正在设计一个数据库(在PostgreSQL 9.6上),该数据库将存储来自分布式应用程序的数据。由于应用程序的分布式性质,SERIAL由于潜在的竞争条件,我不能使用自动增量整数()作为主键。 自然的解决方案是使用UUID或全局唯一标识符。Postgres带有内置UUID类型,非常适合。 UUID存在的问题与调试有关:这是一个非人类友好的字符串。标识符ff53e96d-5fd7-4450-bc99-111b91875ec5什么都没告诉我,而ACC-f8kJd9xKCd虽然不能保证唯一,但告诉我我正在处理一个ACC对象。 从编程的角度来看,调试与几个不同对象相关的应用程序查询是很常见的。假设程序员错误地ACC在ORD(order)表中搜索(account)对象。使用人类可读的标识符,程序员可以立即识别问题,而在使用UUID时,他将花费一些时间来找出问题所在。 我不需要UUID的“保证”唯一性;我确实需要一些空间来生成没有冲突的密钥,但是UUID太过分了。同样,在最坏的情况下,如果发生冲突(数据库拒绝它并且应用程序可以恢复),也不会是世界末日。因此,考虑到折衷,较小但对人类友好的标识符将是我的用例的理想解决方案。 识别应用程序对象 我想出的标识符具有以下格式:{domain}-{string},其中{domain}用对象域(帐户,订单,产品)代替,并且{string}是随机生成的字符串。在某些情况下,甚至可能{sub-domain}在随机字符串之前插入一个。让我们忽略的长度{domain},并{string}为保证唯一性的目的。 如果该格式有助于索引/查询性能,则可以具有固定大小。 问题 知道: 我想使用类似格式的主键ACC-f8kJd9xKCd。 这些主键将成为几个表的一部分。 所有这些键都将在6NF数据库上的多个联接/关系中使用。 大多数表的大小将为中到大(平均约100万行;最大的约1亿行)。 关于性能,什么是存储此密钥的最佳方法? 以下是四种可能的解决方案,但是由于我对数据库的经验很少,因此我不确定哪种数据库(最好)是最好的。 考虑的解决方案 1.存储为字符串(VARCHAR) (Postgres CHAR(n)和和之间没有区别VARCHAR(n),因此我忽略了CHAR)。 经过一些研究,我发现,与的字符串比较VARCHAR(特别是在join操作上)比使用慢INTEGER。这是有道理的,但是我应该在这种规模上担心吗? 2.存储为二进制(bytea) 与Postgres不同,MySQL没有本机UUID类型。有几篇文章解释了如何使用16字节BINARY字段而不是36 字节字段来存储UUID VARCHAR。这些帖子使我想到了将密钥存储为二进制文件(bytea在Postgres上)。 这样可以节省大小,但我更关心性能。我很少能找到解释比较快速的解释:二进制或字符串比较。我相信二进制比较会更快。如果是的话,那么即使程序员现在每次必须对数据进行编码/解码,也bytea可能比更好VARCHAR。 我可能是错的,但我认为两者bytea并VARCHAR会(通过文字或文字),由字节比较(平等)字节。有没有一种方法可以“跳过”此逐步比较,而只是比较“整个过程”?(我不这么认为,但是不进行成本检查)。 我认为按原样存储bytea是最好的解决方案,但是我想知道是否还有其他选择我会忽略。此外,我在解决方案1上表达的同样担忧仍然成立:比较开销是否足以让我担心? “创意”解决方案 我想出了两个非常有效的“创意”解决方案,但我不确定在什么程度上使用(即,如果我无法将它们扩展到表中的几千行)。 3.储存为,UUID但附有“标签” 不使用UUID的主要原因是,程序员可以更好地调试应用程序。但是,如果我们可以同时使用两者:数据库将所有键UUID仅存储为s,但是在进行查询之前/之后包装对象。 例如,程序员要求ACC-{UUID},数据库将忽略ACC-零件,获取结果,然后将所有结果返回为{domain}-{UUID}。 对于某些带有存储过程或函数的黑客来说,这也许是可能的,但是我想到了一些问题: 这(在每个查询中删除/添加域)是否会产生大量开销? 这有可能吗? 我以前从未使用过存储过程或函数,因此不确定是否可能。有人可以照亮吗?如果我可以在程序员和存储的数据之间添加一个透明层,那似乎是一个完美的解决方案。 4.(我的最爱)存储为IPv6 cidr 是的,你没有看错。事实证明,IPv6地址格式完美解决了我的问题。 我可以在前几个八位位组中添加域和子域,并使用其余的作为随机字符串。 该碰撞几率都OK。(虽然我不会使用2 ^ 128,但仍然可以。) 平等比较(希望)得到了优化,所以我可能会比简单地使用获得更好的性能bytea。 实际上,我可以执行一些有趣的比较,例如contains,具体取决于域及其层次结构的表示方式。 例如,假设我使用代码0000来表示域“产品”。密钥0000:0db8:85a3:0000:0000:8a2e:0370:7334将代表产品0db8:85a3:0000:0000:8a2e:0370:7334。 这里的主要问题是:与相比bytea,使用cidr数据类型有什么主要的优点或缺点?

1
为具有多个多对多关系的视频游戏业务领域设计数据库
我对数据库设计比较陌生,因此决定创建自己的假设数据库进行实践。但是,我难以建模和规范化它,因为我认为存在许多多对多(M:N)关系。 一般方案说明 该数据库旨在保留有关在Zelda系列上工作过的各种人员的数据。我想跟踪的控制台(S) ,一个游戏可以玩上,员工是曾在部分游戏的发展,乔布斯的员工有(很多员工在不同的工作职位在多个游戏等) 商业规则 多个员工可以从事多个游戏。 多个游戏可以在同一控制台上。 多个控制台可以是同一游戏的平台。 多个雇员可以具有相同的工作。 一个雇员可以有多个工作。 一个游戏可以有多个雇员。 一个游戏可以有多种类型的乔布斯在它的发展 多个游戏可以附加相同类型的作业。 一个控制台可以有多个人做这个工作。 一个人可以在多个控制台上工作。 属性名称和样本值 员工姓名,可以分成第一和最后(例如“约翰”和“李四”) 游戏标题(例如“时间之笛”) 职务(例如“关卡设计”,“导演”,“沉着”,“关卡设计师”,“程序员”,“本地化”等)。 控制台名称(例如“ Game Boy Advance”) 问题 到目前为止,无论我设计什么,似乎到处都存在感兴趣的实体类型之间的数据冗余和M:N关系。但是,我认为数据库设计人员必须始终遇到这种问题,因此必须找到解决方案。 注意:我很容易找到填充表的数据,问题是将其组织到具有标准化表格的数据库中。

2
递归CTE为所有子代查找总计
这是我要使用递归T-SQL查询(大概是CTE)与以下预期结果进行搜索的程序集树。我想知道给定零件的每个组件的总数。 这意味着如果我搜索“铆钉”,我想知道装配体中每个级别的总数量,而不仅仅是直接子数量。 Assembly (id:1) | |-Rivet |-Rivet |-SubAssembly (id:2) | | | |-Rivet | |-Bolt | |-Bolt | |-SubSubAssembly (id:3) | | | |-Rivet | |-Rivet | |-SubAssembly (id:4) |-Rivet |-Bolt DESIRED Results ------- ID, Count 1 , 6 2 , 3 3 , 2 4 , 1 目前,我可以得到直系父母,但想知道如何扩展我的CTE,以使我可以将此信息向上滚动。 With …

4
区块链(比特币)作为数据库?
我正在阅读此BBC新闻文章和以下摘录,引起了我的注意。听起来像“ 永远在线”可用性组或“ 高可用性镜像”,也许自动包含了安全性。 区块链是否可能成为现代,高交易量应用程序的潜在数据库解决方案? 很容易看出它对于诸如个人病历之类的小额交易的价值,但是大容量数据库又如何呢? 什么是区块链? 区块链依靠密码学来允许一组计算机在不需要中央参与者的情况下对全局记录进行更改。 取消中间商可以减少几乎每个部门的成本。 区块链是一个分类账,按时间顺序或“链”记录发生在称为“块”的数据集合中的所有事件。 作为一种货币,这是一个重要的功能,因为它使用户可以确保自己的数字货币是一种,就像钱包中每个钞票的唯一性一样。 “区块链技术将成为我们创造资产的方式,因为它使您无需复制即可传输数字信息,”建设区块链网络的Chain.com首席执行官亚当·卢德温(Adam Ludwin)说。 区块链可用于跟踪各种信息的历史并保持其价值,例如,医生可以使用它来更新病历。 由于对区块链的每次更改都是在整个网络中同时进行的,因此不会丢失任何信息,并且由于无法撤消更改,系统将保持其透明性。需要一个特殊的密钥来更改每个块,因此个人可以通过保护该密钥来保护其记录安全。

4
在数据库中存储公交路线
我进行了一些研究,发现应该将路线存储为停靠点序列。就像是: Start -> Stop A -> Stop B -> Stop C -> End 我创建了三个表: 路线 停止 路线停靠点 ...其中RouteStops是联结表。 我有类似的东西: 路线 +---------+ | routeId | +---------+ | 1 | +---------+ | 2 | +---------+ 车站 +-----------+------+ | stationId | Name | +-----------+------+ | 1 | A | +-----------+------+ | 2 | …


1
为什么时区在Postgres的0001年有如此疯狂的UTC偏移量?
在Postgres 9.5中,我很惊讶地看到下面的年份在尝试年份0001(没有年份0 0000)时看到。 偏移量-07:52:58? 一些示例代码。请注意,我混合使用TIMESTAMP WITH TIME ZONE和TIMESTAMP WITHOUT TIME ZONE,因此请仔细阅读。 SET TIME ZONE 'America/Los_Angeles' ; SELECT (TIMESTAMP WITH TIME ZONE '2015-01-01 00:00:00.0', TIMESTAMP WITH TIME ZONE '0001-01-01 00:00:00.0Z', TIMESTAMP WITHOUT TIME ZONE '0001-01-01 00:00:00.0Z') ; ("2015-01-01 00:00:00-08","0001-12-31 16:07:02-07:52:58 BC","0001-01-01 00:00:00") 我对第二个值感到惊讶:0001-12-31 16:07:02-07:52:58 BC。我知道我们必须向后退8 America/Los_Angeles个小时,比UTC 落后8个小时,但要相差-08:00。但不是-08:00偏移量是-07:52:58。为什么? UTC下没问题 在UTC下输入数据时没有这种问题。 SET TIME …

3
索引对更新列不在索引中的更新语句的影响
我经常看到人们说索引变慢update,delete并且insert。这用作一揽子声明,就好像它是绝对的一样。 在调整数据库以提高性能的同时,我不断遇到这种情况,这种情况似乎在逻辑上对我来说与该规则相矛盾,而且我在任何地方都找不到其他方式可以说或解释的人。 在SQL Server中,并且我相信/假定将使用大多数其他DBMS,您的索引是根据您指定的特定列创建的。插入和删除将始终影响整个行,因此没有办法不会影响索引,但是更新似乎更加独特,它们可以专门影响某些列。 如果我有未包含在任何索引中的列并更新了它们,它们是否会因为我在该表中的其他列上有索引而放慢了速度? 例如,在我的User表中,我有一个或两个索引,主键是Identity / Auto Increment列,外键列上可能还有另一个。 如果我更新没有索引直接在其上的列(例如说他们的电话号码或地址),由于在任何一种情况下我在该表的其他列上都有索引,此更新是否会变慢?我要更新的列不在索引中,因此从逻辑上讲,不应更新索引,不是吗?如果有的话,如果我使用WHERE子句中的索引,我认为它们会加快速度。

3
为什么SQL Server会忽略索引?
我有一个表,CustPassMaster其中有16列,其中一个是CustNum varchar(8),并且创建了一个index IX_dbo_CustPassMaster_CustNum。当我运行SELECT语句时: SELECT * FROM dbo.CustPassMaster WHERE CustNum = '12345678' 它完全忽略索引。这让我感到困惑,因为我还有另一个表,CustDataMaster其中包含更多列(55),其中一个是CustNum varchar(8)。我IX_dbo_CustDataMaster_CustNum在此表的此列()上创建了一个索引,并使用了几乎相同的查询: SELECT * FROM dbo.CustDataMaster WHERE CustNum = '12345678' 它使用我创建的索引。 这背后有什么具体的理由吗?为什么要使用from的索引CustDataMaster,而不使用from的索引CustPassMaster?是由于列数少吗? 第一个查询返回66行。对于第二个,返回1行。 另外,还要注意:CustPassMaster具有4991条记录和CustDataMaster5376条记录。这可能是忽略索引的原因吗?CustPassMaster也有具有相同CustNum值的重复记录。这是另一个因素吗? 我将此主张基于两个查询的实际执行计划结果。 这是DDL CustPassMaster(具有未使用的索引的DDL ): CREATE TABLE dbo.CustPassMaster( [CustNum] [varchar](8) NOT NULL, [Username] [char](15) NOT NULL, [Password] [char](15) NOT NULL, /* more columns here */ [VBTerminator] …

3
数据库灾难预防
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 4年前关闭。 我的数据库大于250GB。我使用第三方工具进行计划的备份。 计划数据库备份是保护SQL Server数据库免受损坏的最佳方法吗?还是可以推荐其他东西?

1
删除未使用的索引-评估意外的危险
根据DMV统计数据,我们有一个非常大的数据库,其中包含数百个未使用的索引,自从服务器在7月最后一次重新启动以来,该索引一直在累积。我们的一名DBA做出了以下警告性声明,这对我来说没有意义: 在删除索引之前,我们需要确定它是否不执行唯一性约束,因为查询优化器可能需要该索引存在。 每当创建索引时,都会在SQL Server中创建与该索引相关的统计信息。查询可能未使用索引,但可能正在使用其统计信息。因此,我们可能会遇到这样的情况:在删除索引之后,特定的查询性能会变得很差。SQL Server不保留统计信息的使用情况统计信息。尽管我们在数据库上启用了“自动创建统计信息”功能,但是我不知道在查询优化器创建丢失的统计信息之前必须在内部满足哪些所有参数。 关于#1,在我看来,SQL Server实际上会在完成插入/更新之前对索引进行一次搜索以确定唯一性,因此,该索引不会显示为未使用。 关于#2,这真的有可能吗? 顺便说一句,当我说不使用索引时,我的意思是没有搜寻也没有扫描。
16 sql-server  index 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.