¿Cómo se consulta un conjunto de 1 y 0 de caracteres de una base de datos?
Pregunta
Supongamos que tenía una larga serie de caracteres que son 1 o 0, como una especie de bitvector, pero en una columna de base de datos. ¿Cómo se consulta para saber qué se fijan los valores / ningún conjunto? Digamos que usted necesita saber si el carbón de leña y carbón 500 1500 son "verdadero" o no.
Solución
SELECT
Id
FROM
BitVectorTable
WHERE
SUBSTRING(BitVector, 500, 1) = '1'
AND SUBSTRING(BitVector, 1000, 1) = '1'
No índice puede ser utilizado para este tipo de consulta, sin embargo. Cuando tiene muchas filas, esto va a ser lento muy rápidamente.
Editar: En SQL Server, al menos, todas las funciones de cadena incorporados son determinista. Eso significa que usted podría considerar la posibilidad de hacer columnas calculadas en base a la subcadena () los resultados de todo el valor combinado, poner un índice en cada uno de ellos . Inserciones serán más lentos, tamaño de la tabla se incrementará, pero las búsquedas será muy rápido.
SELECT
Id
FROM
BitVectorTable
WHERE
BitVector_0500 = '1'
AND BitVector_1000 = '1'
Edición # 2: El para SQL Server son:
- 1.024 columnas por tabla normal
- 30.000 columnas por tabla "amplia"
Otros consejos
En MySQL, usando algo subcadena como
select foo from bar
where substring(col, 500,1)='1' and substring(col, 1500,1)='1';
Esto será bastante ineficaz, sin embargo, es posible que desee volver a pensar su esquema. Por ejemplo, podría almacenar cada bit por separado para el espacio solución de compromiso para la velocidad ...
create table foo
(
id int not null,
bar varchar(128),
primary key(id)
);
create table foobit
(
int foo_id int not null,
int idx int not null,
value tinyint not null,
primary key(foo_id,idx),
index(idx,value)
);
Lo cual se va a consultar
select foo.bar from foo
inner join foobit as bit500
on(foo.id=bit500.foo_id and bit500.idx=500)
inner join foobit as bit1500
on(foo.id=bit1500.foo_id and bit1500.idx=1500)
where
bit500.value=1 and bit1500.value=1;
Es evidente que consume más capacidad de almacenamiento, pero debería ser más rápido para aquellas operaciones de consulta que se utiliza un índice.
Me convierto la columna de múltiples bits columnas y volver a escribir el código en cuestión - máscaras de bit son mucho más rápido que las comparaciones de cadenas. Pero si usted no puede hacer eso, debe utilizar las funciones-db específica. Las expresiones regulares podrían ser una opción
-- Flavor: MySql
SELECT * FROM table WHERE column REGEXP "^.{499}1.{999}1"
select substring(your_col, 500,1) as char500,
substring(your_col, 1500,1) as char1500 from your_table;