首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否将自定义类型映射到多个列?

是否将自定义类型映射到多个列?
EN

Stack Overflow用户
提问于 2013-08-09 21:30:28
回答 1查看 315关注 0票数 0

我需要使用一个大的位掩码(~115位)。存储是mysql,我的orm是storage。在PHP端,我写了一个类来处理任何东西,我知道我需要一个很好的解决方案来存储它,并在MySQL中通过位比较再次找到它。我的想法是使用四个整数列或两个大整数。现在我需要一种映射(PHP Object <=> 2-4 Columns )。在symfony2中有什么我可以使用的东西吗?

EN

回答 1

Stack Overflow用户

发布于 2013-08-10 17:43:01

这并不是经常做的。很多时候,会有一个位类型的列(或者MySQL上的TINYINT ),或者将选项放在另一个表中并执行oneToMany (这将使您的选项易于配置)。位掩码更容易出错,所以要确保你真的想要这个解决方案。话虽如此,但这是如何做到的:

首先是关于MySQL数据类型的一些信息。对于未签名的位掩码,可能是可行的方法。

代码语言:javascript
复制
TINYINT -> 0-255 = 256 combinations = log 256 / log 2 = 8 bits
SMALLINT -> 16 bits
MEDIUMINT -> 24 bits
INT -> 32 bits
BIGINT -> 64 int

那么,115位的这些字段的最佳用法是什么?这是一个NP完全问题,您可以使用贪婪算法。采纳你的建议,使用4x INT和2x BIGINT。总共给了我256个可用的比特。这超出了115位的要求。对于256位,使用4x BIGINT会更有意义。但是,我不能将这些列合并成一个大数字,而且BIGINT的列甚至可能会有问题。如PHP手册中所述:

代码语言:javascript
复制
The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.

为了安全起见(因为我不知道您的平台),我将只使用INT,并使用其中的四个来给我128位。(您仍然需要检查如何处理不支持无符号整数的32位问题!)

这是data :generate:Entities提供给您的:public function getColumn1() {}的默认函数,但是让其他对象访问这个原始的未处理数据似乎不是一个好主意。因此,让我们为此创建自定义函数。

代码语言:javascript
复制
private function getBit($index) {
    if (0 <= $index AND $index <= 31) {
        return ($this->column1 >> $index) & 1;
    } elseif (32 <= $index AND $index <= 63) {
        $index -= 32;
        return ($this->column2 >> $index) & 1;
    } elseif (64 <= $index AND $index <= 95) {
        $index -= 64;
        return ($this->column3 >> $index) & 1;
    } elseif (96 <= $index AND $index <= 127) {
        $index -= 96;
        return ($this->column4 >> $index) & 1;
    }
}

private function setBit($index, $value) {
    if (! is_bool($value)) \BadMethodCallException('value needs to be a boolean'); // A form of type checking to make the interface to the function more clearly
    $value = (int)$value; // not sure if this is needed, just to make sure

    if (0 <= $index AND $index <= 31) {
        $this->column1 = ($this->column1 & ~(1 << $index)) | ($value << $index);
    } elseif (32 <= $index AND $index <= 63) {
        $index -= 32;
        $this->column2 = ($this->column2 & ~(1 << $index)) | ($value << $index);
    } elseif (64 <= $index AND $index <= 95) {
        $index -= 64;
        $this->column3 = ($this->column3 & ~(1 << $index)) | ($value << $index);
    } elseif (96 <= $index AND $index <= 127) {
        $index -= 96;
        $this->column4 = ($this->column4 & ~(1 << $index)) | ($value << $index);
    }
}

Column1用于最低有效位,额外的列添加更多最高有效位。现在我们已经有了处理原始数据的低级函数,可以很容易地使用普通的getter和属性设置。

代码语言:javascript
复制
public function setFlag4($value) {
    $this->setBit(4, $value);
    return $this;
}

public function getFlag4() {
    return $this->getBit(4);
}

当然,您可以在第25位键入任何名称,如hasBananas(),而不是Flag4

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18147824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档