自动生成序列号

时间:2014-03-03 23:12:21

标签: php mysql

我写了下面的计数代码,目的是让它为我的数据生成自动序列号,代替删除行后的MySQL序列号。但是当我运行它时,我没有观察到MySQL表的任何条目。我后来将代码更改为Dreamweaver插入记录,在那里我观察到SN(序列号)字段不需要为NULL。

通过要求我在发布之前输入SN字段的值意味着此行代码:“$ query = ......”和“$ sn = ......”将不会生成预期的值它的。

所以原则上我需要帮助来了解如何从1创建一个自动序列号到将要创建的数据。

<?php
if(isset($_POST['submit']))
{
    $query  = mysql_query("SELECT COUNT(*) as counter FROM tbl_donors");
    $sn     = mysql_num_rows($query) + 1;
    $donorname      = $_POST['donorname'];
    $designation    = $_POST['designation'];
    $address        = $_POST['address'];
    $city       = $_POST['city'];
    $state      = $_POST['state'];
    $country        = $_POST['country'];
    $phone      = $_POST['phone'];
    $emailaddr      = $_POST['emailaddr'];
    $user_name      = $_POST['user_name'];

    mysql_select_db ($database_xxxxxxxxxx,$xxxxxxxxxx);
   $query = ("INSERT INTO tbl_donors (donor_id, sn, donorname, designation, address , city, state, country , phone, emailaddr, user_name) VALUES ('', '$sn', '$donorname' , '$designation', '$address', '$city' , '$state', '$country', '$phone, '$emailaddr', '$user_name')");
    $results = mysql_query($query,$xxxxxxxxxx) or die
    ("Could not execute query : $query." . mysql_error());
    mysql_close();
}  
?>

2 个答案:

答案 0 :(得分:2)

您需要配置MySQL表,以便sn列启用AUTO_INCREMENT。请考虑the MySQL 5.0 Reference on AUTO_INCREMENT中的此示例:

CREATE TABLE animals (
 id MEDIUMINT NOT NULL AUTO_INCREMENT,
 name CHAR(30) NOT NULL,
 PRIMARY KEY (id)
) ENGINE=MyISAM;

INSERT INTO animals (name) VALUES
 ('dog'),('cat'),('penguin'),
 ('lax'),('whale'),('ostrich');

SELECT * FROM animals;

返回:

+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  2 | cat     |
|  3 | penguin |
|  4 | lax     |
|  5 | whale   |
|  6 | ostrich |
+----+---------+

在此示例中,没有任何内容作为id传递,但结果是自动生成的。

您应该为表格中的sn列定义一些链接。

编辑:假设你绝对觉得你有一个额外的,偏移的,递增的列,一个选项是让它出现所以当你查询表时。在上面的示例中,假设我们需要一个额外的列sn,并且idsn之间的差异为7.我们可以执行以下操作:

SELECT *, (`id` + 7) as `sn` FROM animals;

返回:

+----+---------+----+
| id | name    | sn |
+----+---------+----+
|  1 | dog     |  8 |
|  2 | cat     |  9 |
|  3 | penguin | 10 |
|  4 | lax     | 11 |
|  5 | whale   | 12 |
|  6 | ostrich | 13 |
+----+---------+----+

请注意,虽然您可以在sn和其他语句中使用JOIN,但您将无法在其他表中将其用作外键。

答案 1 :(得分:0)

在MySQL中,每个表只能有一个自动增量字段。这是生成唯一值的正确方法,就像您要求每行一样。

http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html

您使用的方法容易出错。当你测试它可能有效,但当它被多个用户使用时,它将导致重复的id。这是因为如果用户和用户同时请求,他们将同时获得计数,向其添加1,然后插入相同的值。使用自动增量字段可以避免此问题。它也更快更容易使用。

[编辑]

用户询问是否没有其他办法可以做到这一点。当然还有其他方法可以做到这一点,但几乎在所有情况下这都是正确的。即使每个表需要不止一个,在MySQL中执行此操作的最佳方法可能是创建第二个表以获得另一个自动增量。

那说我会提出其中两种选择。问题的关键在于需要一个原子计数器,即一个不受上述竞争条件影响的计数器,并且将始终返回下一个唯一ID。一个这样的原子计数器源是memcache。 Memcache提供了一个原子增量,可以用作唯一ID的源。像所有解决方案一样,这会导致它失败,如果你的memcache失败,你将失去你的状态,计数器将重新开始,因此不那么独特。

另一种方法是使用MySQL锁。这可以是一个表锁,在你锁定表,选择最大id增量,插入和解锁表时,这也需要使用事务,因此会使可能非常简单的代码变得更加复杂。您也可以使用MySQL任意应用程序级锁定方案。

https://dev.mysql.com/doc/refman/5.0/en/internal-locking.html https://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock

实施这种替代方案的复杂性已经足够,如果您还不知道我刚才解释的内容,您应该坚持使用自动增量字段,它们非常易于使用并且相当防弹。