我在php和sql server 2005中有一个系统,我创建了一个具有相关数字的表单,我用php ej增加了这个数字。 $ i ++但是当两个人同时按下按钮保存这个表格时,它在数据库中创建了两个相同数字的表格,这是我的代码:
$correlativo=$correlativo+1;
$queryVeri="SELECT * FROM FacturaCabecera WHERE NumFactura='$correlativo'";
$respVeri=EjecutarlocalFA($queryVeri);
if(count($respVeri)!=0)
{
$numeroFactura=$numeroFactura+1;
}
INSERT INTO FacturaCuerpo([num_factura])VALUES('$correlativo');
为了解决这个问题,我试图验证表中是否存在相关数字,如果存在,我再次递增数字并插入表中,这不重复数字但不起作用,¿我能怎么做?我希望你能帮助我。
相关的数字必须每六个月再次从1开始我不知道是否有可能有两个主键自动增量
答案 0 :(得分:1)
num_factura必须是数据库中的主键,您可以将此字段设为自动增量。如果你这样做,你不再需要$ correlativo了。
你必须有这样的东西:
if(count($raspVeri != 0)) insert();
//insert into FacturaCuerpo ("desc", "qty", "whatever") values ($desc, $qty, $whatever);
让MySql处理“numFactura”。另一个建议,尝试使用PDO。祝你好运!
答案 1 :(得分:1)
从Instagram的工程页面中提取,了解他们如何处理主键:
http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram
存在ID生成问题的许多现有解决方案;以下是我们考虑的一些问题:
在网络应用程序中生成ID
这种方法使ID生成完全取决于您的应用程序,而不是数据库。例如,MongoDB的ObjectId,长度为12个字节,并将时间戳编码为第一个组件。另一种流行的方法是使用UUID
优点:
每个应用程序线程独立生成ID,最大限度地减少故障点和ID生成争用
如果您使用时间戳作为ID的第一个组件,则ID仍可按时间排序
缺点:
通过专门服务生成ID
Ex:Twitter的Snowflake,一种Thrift服务,它使用Apache ZooKeeper协调节点,然后生成64位唯一ID
优点:
缺点:
数据库故障单服务器
使用数据库的自动递增功能来强制执行唯一性。 Flickr使用这种方法,但有两个票据DB(一个在奇数上,另一个在偶数上)以避免单点故障。
优点:
缺点:
在上述所有方法中,Twitter的Snowflake最接近,但运行ID服务所需的额外复杂性是反对它的一点。相反,我们采用了概念上类似的方法,但将其引入PostgreSQL。
我们的分片系统由数千个“逻辑”分片组成,这些分片在代码中映射到更少的物理分片。使用这种方法,我们可以从几个数据库服务器开始,最终转移到更多,只需将一组逻辑分片从一个数据库移动到另一个数据库,而无需重新打包任何数据。我们使用Postgres的模式功能使脚本和管理变得容易。
模式(不要与单个表的SQL模式混淆)是Postgres中的逻辑分组功能。每个Postgres DB都可以有多个模式,每个模式可以包含一个或多个表。表名只能是每个模式唯一,而不是每个数据库,默认情况下,Postgres会将所有内容放在名为“public”的模式中。
每个'逻辑'分片都是我们系统中的Postgres模式,每个模式中都存在每个分片表(例如,喜欢我们的照片)。
我们通过使用PL / PGSQL,Postgres的内部编程语言和Postgres现有的自动增量功能,将ID创建委托给每个分片内的每个表。
我们的每个ID都包含:
让我们来看一个例子:让我们说它是2011年9月9日,下午5点,我们的'纪元'从2011年1月1日开始。自我们的纪元开始以来有1387263000毫秒,所以开始我们的ID ,我们用左移填充最左边的41位:
id = 1387263000 << (64-41)
接下来,我们为我们尝试插入的特定数据获取分片ID。假设我们按用户ID进行分片,并且有2000个逻辑分片;如果我们的用户ID是31341,则分片ID为31341 % 2000 -> 1341
。我们用这个值填充接下来的13位:
id |= 1341 << (64-41-13)
最后,我们采用自动递增序列的下一个值(此序列对每个模式中的每个表都是唯一的)并填写剩余的位。假设我们已经为这个表生成了5,000个ID;我们的下一个值是5,001,我们采用1024和mod(因此它适合10位)并包含它:
id |= (5001 % 1024)
我们现在拥有了ID,我们可以使用RETURNING关键字作为INSERT
的一部分返回应用服务器。
这是实现所有这些的PL / PGSQL(对于示例模式安装):
CREATE OR REPLACE FUNCTION insta5.next_id(OUT result bigint) AS $$
DECLARE
our_epoch bigint := 1314220021721;
seq_id bigint;
now_millis bigint;
shard_id int := 5;
BEGIN
SELECT nextval('insta5.table_id_seq') %% 1024 INTO seq_id;
SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
result := (now_millis - our_epoch) << 23;
result := result | (shard_id << 10);
result := result | (seq_id);
END;
$$ LANGUAGE PLPGSQL;
创建表时,我们会这样做:
CREATE TABLE insta5.our_table (
"id" bigint NOT NULL DEFAULT insta5.next_id(),
...rest of table schema...
)
就是这样!在我们的应用程序中唯一的主键(作为奖励,在其中包含分片ID以便于映射)。