我最近开始了一项新工作,并注意到所有SQL表都使用GUID数据类型作为主键.
在我以前的工作中,我们使用整数(自动增量)作为主键,在我看来,它更容易使用.
例如,假设你有两个相关的表; Product和ProductType - 我可以轻松地交叉检查特定行的两个表的'ProductTypeID'列,以快速映射我脑中的数据,因为它易于存储数字(2,4,45等),而不是(E75B92A3- 3299-4407-A913-C5CA196B3CAB).
额外的挫折感来自于我想了解表格是如何相关的,遗憾的是没有数据库图表:(
很多人说GUID是更好的,因为您可以在C#代码中定义唯一标识符,例如使用NewID()而不需要SQL SERVER来执行此操作 - 这也允许您临时知道ID将是什么....但我已经看到有可能仍然检索'下一个自动递增的整数'.
DBA承包商报告说,如果我们使用Integer类型而不是GUIDS,我们的查询可以快30%...
为什么GUID数据类型存在,它真正提供了哪些优势?...即使是某些专业人士的选择,必须有一些很好的理由来解释为什么它的实现?
我们正在将应用程序从 spring-boot 2.4.3 升级到 2.7.0。Hibernate核心版本是5.6.9.Final。2.7.0是第一个使用H2数据库2.1.212的版本,我们正在使用它进行测试。我根据他们的迁移到 2.0 的指南做了一些更改,但我遇到了一个尚未找到解决方案的问题。
在一些集成测试中,我们在该类中运行测试之前使用 SQL 脚本插入数据。例如,脚本在表中插入 3 个项目,然后测试插入第 4 个项目并更新已存在的最初 3 个项目之一。
执行插入的测试失败并出现以下错误
DataIntegrityViolationException. Error message: could not execute statement; SQL [n/a]; constraint ["PRIMARY KEY ON studio.exercise(id) ( /* key:1 */ 1, 'Test Exercise', FALSE, 'TEST', NULL, 1, 'TEST', TIMESTAMP '2021-01-01 16:00:13', NULL, NULL)";
SQL statement: insert into exercise (id, created_by, created_on, modified_by, modified_on, archived, image, organization_id, title, type) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?) [23505-212]]; nested exception is org.hibernate.exception.ConstraintViolationException: could …Run Code Online (Sandbox Code Playgroud) 我正在使用MySQL 5.我需要为我的自动增量字段将种子值设置为1000.我怎么设置它?
我在一个有4列的表上工作,第一个是一个名为id的自动递增整数.
如果我要使用mysqli预处理语句插入到此表中,我一直无法插入有效的查询.使用PHPmyAdmin它告诉我将它赋予NULL.我试过这个:
$query = "INSERT INTO tbl (id, col2, col3, col4) VALUES ('NULL', ?, ?, ?)";
$stmt -> bind_param("ssi", $col2, $col3, $col4)
Run Code Online (Sandbox Code Playgroud)
还有这个
$query = "INSERT INTO tbl (id, col2, col3, col4) VALUES (NULL, ?, ?, ?)";
$stmt -> bind_param("ssi", $col2, $col3, $col4)
Run Code Online (Sandbox Code Playgroud)
并且只给出bind_param 3个参数(最后3个).这些都不奏效.我也试过这个:
$null = NULL;
$query = "INSERT INTO tbl (id, col2, col3, col4) VALUES (?, ?, ?, ?)";
$stmt -> bind_param("issi", $null, $col2, $col3, $col4);
Run Code Online (Sandbox Code Playgroud)
这些都不起作用.是否有标准化的方式插入这种类型的表?
我不明白Perl中的自动增量字母.
这个例子似乎完全可以理解:
$a = 'bz'; ++$a;
ca #output
Run Code Online (Sandbox Code Playgroud)
b增加到c.没有什么z可去的,所以它可以追溯到a(或至少这是我看到的过程).
但后来我遇到这样的陈述:
$a = 'Zz'; ++$a;
AAa #output
Run Code Online (Sandbox Code Playgroud)
和:
$a = '9z'; ++$a;
10 #output
Run Code Online (Sandbox Code Playgroud)
为什么不增加Zz收益Aa?为什么不增加9z回报0z呢?
谢谢!
我只是使用MySQL Query Browser创建一个新表,并注意到Auto Increment Column下有一个勾号.这是如何运作的?
以编程方式添加到数据库时,我只是添加一个数字,然后数据库会自动增加该数字吗?
每当新用户在我的网站上注册时,我希望他们的客户ID(仅限整数)自动递增,因此我不必尝试随机生成唯一编号.
这可以简单地完成吗?
谢谢!
我有一个带ID的表,这个ID是自动增量和主键,我第一次插入到该表时,ID从0开始,但在我从该表中删除所有值并再次插入它之后,ID不会从0开始,但是从ID的最后一个值开始,出了什么问题?我可以将值重置为0吗?
LAST_INSERT_ID() 通过自动增量列返回为当前连接生成的最新id,但是如何判断该值是来自最后一个插入而不是来自同一连接上的先前插入?
假设我正在使用池中的连接,该连接可能在我获得连接之前插入了一行,并且我执行了一个条件插入:
insert into mytable (colA)
select 'foo' from bar
where <some condition>;
select LAST_INSERT_ID();
Run Code Online (Sandbox Code Playgroud)
我无法知道返回的值是否来自我的插入.
我想到的一种方式是:
@previousId := LAST_INSERT_ID();
insert into mytable (colA)
select 'foo' from bar
where <some condition>;
select if(LAST_INSERT_ID() != @previousId, LAST_INSERT_ID(), null);
Run Code Online (Sandbox Code Playgroud)
有没有办法"清除"该LAST_INSERT_ID()值,所以我知道如果返回非零值,它是由我的SQL引起的新值?
假设我们使用 Unix 时间戳列在 Sqlite 数据库中记录事件ts:
CREATE TABLE data(ts INTEGER, text TEXT); -- more columns in reality
Run Code Online (Sandbox Code Playgroud)
并且我们想要快速查找日期时间范围,例如:
SELECT text FROM data WHERE ts BETWEEN 1608710000 and 1608718654;
Run Code Online (Sandbox Code Playgroud)
像这样,EXPLAIN QUERY PLAN给出SCAN TABLE data哪个不好,所以一个明显的解决方案是创建一个带有CREATE INDEX dt_idx ON data(ts).
然后问题就解决了,但是对于一个已经增加的序列/已经排序的列维护一个索引,我们可以直接在 O(log n) 中使用B 树搜索,这是一个相当糟糕的解决方案。在内部,这将是索引:ts
ts rowid
1608000001 1
1608000002 2
1608000012 3
1608000077 4
Run Code Online (Sandbox Code Playgroud)
这浪费了数据库空间(当查询必须首先查看索引时浪费 CPU)。
为避免这种情况:
(1)我们可以使用ts的INTEGER PRIMARY KEY,所以ts会是 …
auto-increment ×10
mysql ×5
database ×3
sqlite ×2
guid ×1
h2 ×1
hibernate ×1
insert ×1
mysqli ×1
perl ×1
php ×1
sql ×1
sql-server ×1
time-series ×1