您经常会看到数据库字段设置为255个字符,传统/历史原因是什么?我认为它与分页/内存限制和性能有关,但255和256之间的区别总是让我感到困惑.
varchar(255)
Run Code Online (Sandbox Code Playgroud)
考虑到这是容量或幅度,而不是索引器,为什么255优先于256?是为某种目的保留的字节(终止符还是null或其他)?
推测varchar(0)是无意义的(零容量)?在这种情况下,2 ^ 8的空间应该是256?
是否有其他量级可以提供性能优势?例如,varchar(512)的性能低于varchar(511)或varchar(510)?
对于所有新旧关系数据库,此值是否相同?
免责声明 - 我是开发人员而不是DBA,我使用适合我的业务逻辑的字段大小和类型,但我想知道这种偏好的历史原因,即使它不再相关(甚至是更多,如果它仍然相关).
感谢您的回答,似乎有一些共识认为一个字节用于存储大小,但这并不能在我的脑海中明确解决问题.
如果元数据(字符串长度)存储在相同的连续内存/磁盘中,则有一定意义.1个字节的元数据和255个字节的字符串数据非常适合彼此,并且适合256个连续的存储字节,这可能是整洁的.
但是......如果元数据(字符串长度)与实际字符串数据(可能在主表中)分开存储,那么将字符串数据的长度约束一个字节,只是因为它更容易只存储1个字节的整数元数据似乎有点奇怪.
在这两种情况下,它似乎都是一个微妙的可能取决于数据库的实现.使用255的做法似乎相当普遍,所以某个地方的人必须在一开始就为它辩护一个好的案例,有人能记住那个案例是什么吗?程序员在没有理由的情况下不会采用任何新的做法,这必须是新的一次.
我只是想大致了解RDBMSes中使用的视图.也就是说,我知道一个观点是什么以及如何制作一个观点.我也知道我过去曾用过它们.
但我想确保我彻底了解视图的用处以及视图不应该有用的内容.进一步来说:
(并且为了记录,其中一些问题是故意天真的.这部分是概念检查.)
在MSSQL 2005中,我刚刚发现臭名昭着的错误消息:
在表YYY上引入FOREIGN KEY约束XXX可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.
现在,StackOverflow有关于此错误消息的几个主题,所以我已经得到了解决方案(在我的情况下我将不得不使用触发器),但我很好奇为什么会出现这样的问题.
据我了解,他们基本上有两种情况需要避免 - 一个循环和多个路径.一个循环是两个表彼此级联外键的地方.好的,一个循环也可以跨越几个表,但这是基本情况,并且更容易分析.
当TableA具有TableB和TableC的外键时,将有多个路径,TableB也具有TableC的外键.再次 - 这是最基本的案例.
当在任何这些表中删除或更新记录时,我看不到任何问题.当然,您可能需要多次查询同一个表以查看哪些记录需要更新/删除,但这真的是一个问题吗?这是性能问题吗?
在其他SO主题中,人们甚至将使用级联标记为" 有风险 ",并声明" 解决级联路径是一个复杂的问题 ".为什么?风险在哪里?问题出在哪儿?
我最近通过给SQLite一个很好的索引来加速一个复杂的查询.这样的结果让我想知道是否应该索引常用于JOIN或ORDER BY子句的许多其他字段.但是我不想过度热心并让它适得其反:我认为必须有一些理由不创建索引,或者默认情况下每个字段都会被编入索引.
我在这种情况下使用SQLite,但当然也欢迎DBMS不可知的建议.
我们可以获得一系列基本优化技术(从建模到查询,创建索引,视图到查询优化).有一个列表,每个答案一个技术,这将是很好的.作为一个业余爱好者,我会发现这非常有用,谢谢.
为了不太模糊,假设我们使用的是MySQL或Oracle等maintstream数据库,并且数据库将在~10个表中包含500,000-1m左右的记录,其中一些具有外键约束,所有使用最典型的存储引擎(例如:InnoDB for MySQL).当然,定义PK等基础知识以及FK约束.
我经常看到像这样编写SQL的人:
SELECT * from TableA LEFT OUTER JOIN TableB ON (ID1=I2)
Run Code Online (Sandbox Code Playgroud)
我自己写的很简单:
SELECT * from TableA LEFT JOIN TableB ON (ID1=I2)
Run Code Online (Sandbox Code Playgroud)
对我来说,"OUTER"关键字就像线路噪音一样 - 它不会增加额外的信息,只会使SQL混乱.在我所知道的大多数RDBMS中它甚至是可选的.那么......人们为什么还要写呢?这是习惯吗?可移植性?(你的SQL是否真的可移植?)还有其他我不知道的东西?
我的公司让我为Oracle ORM完成Oracle的后端工作.令我惊讶的是,即使对于简单的东西,RDBMS也会有多么不同.我已经学到了很多关于Oracle和其他RDBMS之间差异的知识.出于纯粹的好奇心,我想了解更多.
在将SQL从一个平台移植到另一个平台方面有哪些常见的"问题"?
请,每个答案只有一个问题.
对于这个无知的问题很抱歉,但是什么样的应用程序不需要符合ACID标准的数据库服务器?我有一个SQL Server背景,其中ACID一直"在那里",现在研究其他DBMS让我思考.我能想到的大多数应用都需要原子性或隔离性.谢谢!
我正在将数据从一个数据库架构迁移到另一个.旧模式具有基于邻接列表的分类系统,具有id,category和parent_id.如果一个类别低于一秒,则该类别将第二个id作为其父ID.例如:
+-------------+----------------------+--------+
| category_id | name | parent |
+-------------+----------------------+--------+
| 1 | ELECTRONICS | NULL |
| 2 | TELEVISIONS | 1 |
| 3 | TUBE | 2 |
| 4 | LCD | 2 |
| 5 | PLASMA | 2 |
| 6 | PORTABLE ELECTRONICS | 1 |
| 7 | MP3 PLAYERS | 6 |
| 8 | FLASH | 7 |
| 9 | CD PLAYERS | 6 |
| 10 | 2 …
Run Code Online (Sandbox Code Playgroud) 我正在进行在线调查.大多数问题的答案都是1-5.如果我们需要在调查中添加一个问题,我会使用一个简单的Web表单,将INSERT插入到相应的表中,瞧!调查问的是新问题 - 没有新代码或数据库结构的变化.
我们被要求添加可以获得不同数据类型答案的调查问题.规范是让调查"可配置",以便在未来的任何时候,当有人说"我们需要一个新的调查,询问{text answer question},{1-5 question},{true false question} ,{带有日期作为答案的问题}",我们可以在不改变数据库结构的情况下做到这一点.
我正在尝试考虑存储这些答案的最佳方法,但我提出的每种方法似乎都有点hackish.
有些问题可能有一个是/否或真/假答案,有些可能有一个整数答案("过去一个月你有多少次使用技术支持?"),另一个答案可能有一个日期,一个字符串,一个多个选择具有单个值,具有多个值的多项选择等.或者有时,特定答案值可能会提示子问题("令您失望的是什么......?")
简单的解决方案是将每个问题作为调查中的一个列,将其答案作为调查中的一列,以及是否将其作为调查中的一列.这对我来说感觉很乱 - 这是一张大餐桌; 不是很"关系".
头脑风暴,我能想出的"最佳"方法是为每种答案类型设置一个不同的表,但这样会容易受到数据完整性问题的影响.换句话说,我会
CREATE TABLE `Questions` (...);
CREATE TABLE `TrueFalseAnswers` (...);
ALTER TABLE `TrueFalseAnswers`
ADD CONSTRAINT `TrueFalseAnswers_ibfk_1` FOREIGN KEY (`question_id`)
REFERENCES `Questions` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
CREATE TABLE `TextAnswers` (...);
ALTER TABLE `TextAnswers`
ADD CONSTRAINT `TextAnswers_ibfk_1` FOREIGN KEY (`question_id`)
REFERENCES `Questions` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
Run Code Online (Sandbox Code Playgroud)
等等
上述问题之一是我不能保证仅DDL中的任何问题至少存在一个且只有一个答案.
另一种解决方案可能是在Questions表中为答案设置二进制或字符串列,并将所有答案编码为某种字符串或二进制格式,并将它们存储在答案列中.这为每个问题提供了至少一个且只有一个答案,但后来我无法访问SQL查询中的聚合功能.这让我觉得不是一个非常"关系"的解决方案.
所以,我发现上述想法存在问题.有没有"最好的"方法来解决这个问题?
现在我已经花时间来表达问题和我的想法,似乎我提出的广泛问题是"我想存储任意类型的数据而不进行任何编码......"这是绝望?
我正在使用MySQL,因此我无法访问其他RDBMS可能的内容.
对我来说,这种情况发生的可能性似乎极不可能,因为它可能会导致问题,但我想无论如何我都会问这个问题......
想象一下一个涉及自增 ID 并分配值的事务。在 COMMIT 之前,相关代码会缓存分配的 ID 的副本以供以后参考。然后事务被提交。
假设没有直接的客户端干预(删除或更改记录),是否有任何数据库或情况会在提交后立即自动更改 ID 值,从而使缓存的 ID 不正确?在事务中缓存 ID 总是安全的吗?
我可以想象这种情况发生的一个假设情况是,如果某些 RDBMS 实现莫名其妙地决定有必要拥有无间隙且与时间相关的自动增量值(因为我看到很多人希望这样做的例子)。在这种假设的情况下,我可以想象可能会进行一些神奇的 ID 改组,以填补另一个事务(或其他间隙原因)中 ID 分配后回滚所造成的间隙。这将使缓存的值无效。
有人知道这样的实现或其他缓存杀手吗?
什么是最好的,独立于DBMS的生成ID号的方法,将立即在INSERT语句中使用,保持ID大致按顺序排列?
昨天在从事一个项目时,我想出了一种特殊的1:1关系让我感到疑惑 - 如何最好地实现这一点(显然,我们做错了:D)
这个想法是有两种类型的实体,A和B.它们可以各自独立存在,但它们之间也可以有链接.如果有链接,那么它必须是1:1链接,并且双向工作.
它就像一个瓶子和一个帽子.它们可以分开存在,但是当它们连接在一起时,瓶子将只有一个盖子,并且盖子将仅连接到一个(和相同的)瓶子上.
您如何实现这种关系,同时牢记关于规范化,数据完整性等的所有最佳实践?
补充:几乎忘了说 - 他们每个都有十几个属性,所以将它们放在同一个表中,其中一半字段为NULL是一个非常尴尬的解决方案.此外,可以随时破坏链接并使用其他实体重新创建链接.
rdbms-agnostic ×13
sql ×9
database ×3
rdbms ×3
acid ×1
algorithm ×1
cascade ×1
commit ×1
foreign-keys ×1
indexing ×1
mysql ×1
nested-sets ×1
orm ×1
portability ×1
sqlite ×1
syntax ×1
transactions ×1
views ×1