我需要使用一个大的位掩码(~115位)。存储是mysql,我的orm是storage。在PHP端,我写了一个类来处理任何东西,我知道我需要一个很好的解决方案来存储它,并在MySQL中通过位比较再次找到它。我的想法是使用四个整数列或两个大整数。现在我需要一种映射(PHP Object <=> 2-4 Columns )。在symfony2中有什么我可以使用的东西吗?
发布于 2013-08-10 17:43:01
这并不是经常做的。很多时候,会有一个位类型的列(或者MySQL上的TINYINT ),或者将选项放在另一个表中并执行oneToMany (这将使您的选项易于配置)。位掩码更容易出错,所以要确保你真的想要这个解决方案。话虽如此,但这是如何做到的:
首先是关于MySQL数据类型的一些信息。对于未签名的位掩码,可能是可行的方法。
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手册中所述:
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() {}的默认函数,但是让其他对象访问这个原始的未处理数据似乎不是一个好主意。因此,让我们为此创建自定义函数。
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和属性设置。
public function setFlag4($value) {
$this->setBit(4, $value);
return $this;
}
public function getFlag4() {
return $this->getBit(4);
}当然,您可以在第25位键入任何名称,如hasBananas(),而不是Flag4
https://stackoverflow.com/questions/18147824
复制相似问题