Doctrine 2 + 无符号值

82

在Doctrine 2中,是否可以指定无符号整数列类型?

6个回答

143
/** * @ORM\Column(name="id", type="integer", options={"unsigned"=true}) */
id:
  type: integer
  options:
    unsigned: true

6
在SQLite中使用它将会失败,因为它只支持有符号整数。 - Harmon Wood
这实际上在文档中提到了:http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/defining-models.html#type-modifiers,是的,它是针对数据库特定的。 - gondo
@gondo,那是Doctrine 1。 - glen-84
1
@hardik,正如我们在gondo上看到的那样,链接到github上的doctrine:"repositoryClass:Doctrine\Tests\Models\DDC869\DDC869PaymentRepository id: id: type:integer unsigned:true" - Mikl
2
@hardik 喜欢:options: { unsigned: true } - MauganRa
显示剩余6条评论

22
你可以这样做,但会失去可移植性。使用columnDefinition属性并将其设置为integer unsigned。实际的代码取决于您使用的内容。

columnDefinition:DDL SQL片段,在列名称之后开始并指定完整(非便携!)列定义。此属性允许使用高级RMDBS功能。但是,您应谨慎使用此功能及其后果。如果使用“columnDefinition”,SchemaTool将无法正确检测列上的更改。

Doctrine参考:https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#column

4
在ORM中失去可移植性是不可接受的。请设置精度为0的十进制数。 - Harmon Wood

18

Doctrine 1 文档Doctrine 2 文档 均表示您可以通过以下方式实现:

使用 PHP 注释:

/**
 * @Column(type="integer", name="some_field", options={"unsigned":true})
 */
protected $someField;

Yaml:(请参阅文档

MyEntity:
  fields:
    someField:
      type: integer
      column: some_field
      options:
        unsigned: true

希望这能帮助某人节省时间 ;)


14
小数将允许您处理如此大的数字,并使您保留SchemaTool,只需将比例设置为0即可。
<?php
/**
 * @Column(type="decimal", precision=20, scale=0, nullable=false, unique=true)
 */
Protected $facebookId;

请查看here的完整解释。[编辑](链接失效)。我已经复制了下面的文章。反正是我自己写的 ;)

无符号大数,让你的大脑爆炸!与Doctrine 2一起使用

ORM存在一个固有问题。如果只有某些RDBMS支持数据类型,那么如何允许您仍然使用它。好吧,当涉及到Doctrine 2和无符号数字时,他们有点懒。

我想做的就是存储我的64位Facebook ID。这有多难?好吧,我的RDBMS是MySQL,所以我真正需要的只是一个无符号bigint。

<?php
/**
 * @Column(type="bigint", nullable=false, unique=true, columnDefinition="unsigned")
 */
Protected $facebookId;

这看起来很不错,直到你读到这里:
columnDefinition:DDL SQL片段,从列名后开始并指定完整(非便携式!)列定义。此属性允许利用高级RMDBS功能。但是,如果使用“columnDefinition”,您应该谨慎使用此功能和其后果。如果使用“columnDefinition”,SchemaTool将无法正确检测列上的更改。
基本上,此功能使您可以在列定义中自由形式地插入不受支持的内容。这使得无符号数字在技术上不被支持!更不用说我的开发和QA部署系统严重依赖于SchemaTool了。我们可以感谢Doctrine和sqlite3懒惰的开发人员的结合,为我们带来了这个疯狂的小问题。
这立即促使我进行了一次谷歌搜索。我不喜欢不必要的思考。我找到了什么?每个人都在使用varchars。VARCHARS?!?我差点心脏病发作。这就是不可接受的。
因此,十进制数就登场了。它非常完美。存储大小可变且以二进制形式存储,因此索引速度非常快。我们只需将小数精度设置为零,就可以实现。ORM可以将其转换为任何RDBMS,它足够大,使我们不必担心不支持的有符号/无符号问题,并且速度非常快。decimal(20,0)应该可以很好地处理我们的Facebook大小,即一千八百四十六京四千四百四十六万七千四百四十万七千三百零九亿五千五百五十一万六千一百十五。
<?php
/**
 * @Column(type="decimal", precision=20, scale=0, nullable=false, unique=true)
 */
Protected $facebookId;

完整的写作链接已经失效。如果没有链接,答案就无法正常工作或理解。您能否详细说明或修复链接? - Plínio César
@PutzKipa 我已经将我写的另一篇文章粘贴到了这个答案的底部。 - Harmon Wood
我认为比例和精度被颠倒了。应该是/** @Column(type="decimal", scale=20, precision=0, nullable=false) */ - Brady Emerson
1
@BradyEmerson 为什么它们被翻转了?Precision 告诉我们有多少个小数点。在这种情况下,我们正在劫持一个浮点数来用作整数,因此 Precision 是 0。Scale 是我们必须适应大数字的内存分配大小,因此 20 是最适合我们 Facebook 需求的数字,19 可惜太小,而 0(正如您建议的)甚至无法保存一个数字。 - Harmon Wood
1
至少对于MySQL而言,精度是数字的最大位数;刻度是小数点右侧的数字位数。http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html - Brady Emerson
1
顺便提一下:根据 https://developers.facebook.com/docs/graph-api/reference/v2.1/user,Facebook ID 是字符串。但是无论如何,十进制对于它们可以存储的其他数据来说也很好。 - Levente Pánczél

4

2

我在使用Doctrine 2时遇到了同样的问题,我采用了相同的解决方法,但是有一些优点:

/**
 * @ORM\Column(name="id", type="integer", options={"unsigned"=true})
 */

运行差异迁移命令 bin/console doctrine:migration:diff 将会做一些魔法。实际上,如果该列是其他表中的外键,Doctrine 能够找到它们并应用与相关列相同的更新行。

在您的迁移中,只需要在列类型转换之前删除外键,然后在之后添加它们即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接