【问题标题】:How to create a ticket reference number in PHP and mySQL如何在 PHP 和 mySQL 中创建票证参考号
【发布时间】:2016-08-23 12:42:04
【问题描述】:

我正在使用 PHP 和 mySQL 开发票务系统。 我有一张表supportid 作为我的主键和 AI。

我想添加ticket_number,以便在提交工单时为每个工单分配一个唯一编号。我不能使用 mySQL 来 AI 第二个字段,对吧?

如果我给第一张票一个数字,然后写一个查询在数据库中查找最后一个ticket_number,那么我正在考虑做类似的事情:

$ticket = 1;
$next = $ticket+1;
echo "ticket number: #".$next;

这会起作用还是有更好的方法?

【问题讨论】:

  • 在您的support 表中插入一条记录后,您可以使用insert_id 检索插入的AI id。不需要这个$ticket+1 的东西。
  • @MonkeyZeus 我可以从查询中检索行 ID(我已经考虑过),但我需要我的回复属于同一组,即票号而不是行号。
  • 我不明白。票证怎么不是support 表中的唯一条目?
  • 假设用户提交了一张票,它将获得一个唯一的行 ID。然后我回复它,我的消息得到一个新的/唯一的行 ID。我需要 ticket_number 将对话消息链接在一起...
  • 您不应该在同一个support 表中这样做;它会比你眨眼的速度更快地变成一个无法维护的混乱。研究一个名为 normalization 的概念,并通过创建通过主键和外键相互链接的附加表来分离您的关注点。

标签: php mysql ticket-system


【解决方案1】:

按照MonkeyZeus 的建议,您需要退后一步,重新考虑您的架构。

您希望多行(回复)通过一个 ID(票号)链接在一起。

你肯定希望这个 ID 是另一个表中一行的 ID。

所以你应该有两个表:

  • 一个tickets
  • 另一个replies

第一个将能够保存特定于工单的数据,包括工单的状态(打开、关闭...)、分配给谁(用户的 ID)、创建工单的人(同样是一个 id),并且可能在它被打开和关闭时(尽管这可以通过其他方式推断出来)。

第二个将保存您票证中每个条目的特定数据(初始消息,以及随后的来回回复)。

您还可以有其他表格(或与replies 相同)用于其他类型的操作(工单状态更改、子工单创建等)。

tickets 将有一个唯一的 ID,您可以将其用作票号(可能带有某种前缀,可能以某种方式重新格式化)。

replies 将有一个唯一的 ID(当您想将文件附加到回复或对其进行编辑时很有用)以及与之关联的工单的 ID。

让 Mysql 创建 ID。使用您喜欢的语言的 API 来获取最后插入的行的 ID。

  • 不要根据服务器返回的最大 ID 在客户端增加 ID。比赛条件迫在眉睫。
  • 请勿使用在客户端生成且不保证唯一的 ID

【讨论】:

  • 好的,谢谢。我会看看这个。目前,我有一个简单的表,其中包含 id、user_id、user_name、subject、message、timestamp。接下来我要添加状态等...
  • user_name 可能不应该在那个表中,而应该在一个单独的 users 表中。
  • 是的,但我也想把它放在这里。
  • 感谢您的详细回答。我已经实现了这个模式(参见下面的模式图)并且运行良好。 :) 我在下面选择了我的答案,因为它解决了我最初的问题,但感谢您的额外帮助!
【解决方案2】:

您可以通过以下代码实现。每次都会生成唯一的票号

$brand = '#ref';
$cur_date = date('d').date('m').date('y');
$invoice = $brand.$cur_date;
$customer_id = rand(00000 , 99999);
$uRefNo = $invoice.'-'.$customer_id;
echo $uRefNo;

【讨论】:

  • 好的,我明白了你做了什么……把那个日期和一个随机数结合起来……聪明!这可能行得通。
  • @Hooli 如果您修改date 以包含,它会变得更加独特吗?
  • 参考我的回答
  • @GeraldSchneider 我已经稍微调整了你的代码......认为这应该可以工作:$cur_date = date('sdmy'); $rand_id = rand(00000 , 99999); $ticket = $cur_date.'-'.$rand_id; echo $ticket;
【解决方案3】:

对于良好且唯一的 ID,您有更好的解决方案:

  • 您可以使用基于微时间的 md5 哈希(与 PHP 中的 uniqid 相同,但更安全)
  • 您可以使用具有unique = true 功能的额外列并请求获取此列的最大值并在新插入之前在代码中递增
  • 您可以使用您的支持 ID 作为唯一条目,通过首先插入另一个字段然后取回插入的 ID 以更新您的票证 ID(如果它是您表格的其他组件)或单独显示给您的用户,如果您将其视为您的票证 ID..

【讨论】:

  • 即使它的加密属性在这里并不重要,请勿使用 MD5MD5 损坏。养成使用 SHA-256 或更高版本的好习惯。
  • 另见问题评论。不要根据服务器提供的数据增加客户端。这将导致竞争条件。
【解决方案4】:

@jcaron 我设计了一个模式——这可行吗?

【讨论】:

  • 为什么tickets 中会有ticket_idid?保留一个唯一键(主键)。是否使用自动递增整数 ID(我强烈推荐)或您自己的 varchar ID 取决于您,但您绝对不需要两者。如果您同时保留两者,replies 中的ticket_id 应该引用tickets 的主键,而不是辅助字段(尤其是如果您甚至没有在该字段上设置UNIQUE 约束)。你需要多读一些关于数据库设计的书……
【解决方案5】:

我决定修改@Himanshu kumar 的回答如下(因为它解决了我的原始问题)以使用用户的 id 和时间戳(我已经在使用两者)作为票号:

$user_id = 7; //example from session variable
$cur_date = date('dmyHis'); //timestamp ticket submitted
$ticket = '#'.$user_id.'-'. $cur_date;

这将创建一个具有用户 ID 和日期和时间的唯一变量。我用秒来让它更独特。然后,我将使用查询来查找带有此票证的所有消息/票证。

【讨论】:

  • 欢迎来到非唯一 ID 的世界。因此,如果用户在同一天的 12:01:43 创建了一张票,而在 14:32:43 创建了另一张票,那么您最终会得到相同的 ID。是的,它发生。
  • 我说的是同一用户在同一天创建了两张票。时间可能不同,但您只使用秒(两种情况下都是 43)和日期,因此它们将具有相同的 ID。无论如何,请参阅我的其他 cmets,了解为什么这是一个非常糟糕的主意。
  • 不,不会的。票一将变为 430112,票二将变为 433214。两者都将由用户 ID 预先固定。
  • 好的,让我们重新开始。如果日期是 2016 年 8 月 23 日 12:01:43,date('sdmy') 返回什么?我可以告诉你这不是 430112。
  • 我已经测试过了。在您的示例中,它将类似于:43230816。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 2011-11-23
  • 2010-11-26
  • 1970-01-01
相关资源
最近更新 更多