Esse comportamento está documentado em algum lugar e a precisão dupla total pode ser ativada?
consultas de reprodução:
select 1e-130; /* 0.0...1 result */
select 1e-131; /* 0 result */
reprodução online: https://dbfiddle.uk/5uwlkJaB
Esse comportamento está documentado em algum lugar e a precisão dupla total pode ser ativada?
consultas de reprodução:
select 1e-130; /* 0.0...1 result */
select 1e-131; /* 0 result */
reprodução online: https://dbfiddle.uk/5uwlkJaB
Baseado em documentos Sqlite: https://www.sqlite.org/datatype3.html#type_conversions_prior_to_comparison , especialmente esta declaração:
Se um operando tiver afinidade INTEGER, REAL ou NUMERIC e o outro operando tiver TEXT ou BLOB ou nenhuma afinidade então a afinidade NUMERIC será aplicada ao outro operando.
Eu esperaria a seguinte consulta:
CREATE TABLE `invoice` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
`amount` DOUBLE PRECISION DEFAULT NULL
);
insert into `invoice` (`amount`) values (4.0);
insert into `invoice` (`amount`) values (15.0);
insert into `invoice` (`amount`) values (4.0);
select *,
typeof(amount), amount = '4',
typeof(sum(amount)), sum(amount) = '4', sum(amount) = '4.0', sum(amount) = 4
from invoice
group by id;
para retornar o mesmo resultado para sum(amount) = '4'
cada amount = '4'
linha, pois ambos os tipos de operando têm o mesmo tipo em cada comparação (verificado usando typeof()
, para não, SUM()
a comparação está funcionando conforme o esperado).
Demonstração: http://sqlfiddle.com/#!5/59238/2
SQL é mais do que palavras:
CREATE TABLE "currency" ("id" NUMBER(10) NOT NULL, "currency" VARCHAR2(50) NOT NULL, "name" VARCHAR2(1020) DEFAULT NULL NULL, PRIMARY KEY("id"));
CREATE TABLE "user" ("id" NUMBER(10) NOT NULL, "name" VARCHAR2(1020) DEFAULT NULL NULL, "currency" VARCHAR2(50) DEFAULT NULL NULL, PRIMARY KEY("id"));
CREATE UNIQUE INDEX IDX_6956883FFF467AE9 ON "currency" ("currency");
ALTER TABLE "user" ADD CONSTRAINT FK_8D93D6496956883F6956883F695 FOREIGN KEY ("currency") REFERENCES "currency" ("currency");
ORA-02270: nenhuma chave exclusiva ou primária correspondente para esta lista de colunas
Os tipos de coluna são os mesmos e um índice exclusivo é adicionado.
Por que o FK não pode ser adicionado?
Baseado em documentos SQLite: https://www.sqlite.org/datatype3.html#type_conversions_prior_to_comparison , especialmente esta declaração:
Se um operando tiver afinidade INTEGER, REAL ou NUMERIC e o outro operando tiver TEXT ou BLOB ou nenhuma afinidade, a afinidade NUMERIC será aplicada ao outro operando.
Eu esperaria a seguinte consulta:
CREATE TABLE t (id integer primary key, str varchar(20));
INSERT INTO t (id, str) VALUES (1, '5'), (2, '5u');
SELECT id, 5 = str, 5 >= str, CAST(5 AS NUMERIC) >= str, CAST(str AS NUMERIC) FROM t;
para retornar 5 >= str
= 1
para ambas as linhas, pois o operando do lado esquerdo tem afinidade NUMERIC.
Demonstração: http://sqlfiddle.com/#!5/e9c19/4
Como alterar os agrupamentos padrão listados por SHOW CHARACTER SET
?
Pois utf8
eu preciso alterá-lo para utf8_unicode_ci
.
Ou existe algum switch para impor o _unicode_ci
over _general_ci
para qualquer charsets UTF8xx?
Eu tenho um código bastante complexo, que no início inicia a transação. Depois disso, várias consultas do usuário são realizadas (mais ou menos sem meu controle) e no final a transação é confirmada se tudo correr bem.
O que eu preciso é detectar se a conexão no final ainda está dentro da mesma transação , pois o código do usuário pode consultar o commit/rollback e iniciar uma nova transação.
Qual é a prática da indústria para isso? O banco de dados MySQL pode retornar algum tíquete/ID de transação? Ou a variável de transação de armazenamento MySQL apenas, que será detectável após a confirmação/reversão?
Eu li artigos sobre FORCE
índice, mas como posso forçar o MySQL a IGNORE ALL
indexar?
Eu tentei SELECT * FROM tbl IGNORE INDEX(*)
, mas não tive sucesso.
Quanto ao motivo pelo qual eu (e outros) preciso fazer isso: Por exemplo, eu precisava resumir as estatísticas de referenciadores por tld assim:
SELECT
count(*) as c,
SUBSTRING
(
domain_name,
LENGTH(domain_name) - LOCATE('.', REVERSE(domain_name)) + 2
) as tld
FROM `domains_import`
IGNORE INDEX(domain_name)
GROUP BY tld
ORDER BY c desc
LIMIT 100
...mas sempre tenho que ver quais índices estão definidos ou determinar qual índice será usado via Explicar. Seria muito útil simplesmente escrever IGNORE INDEX ALL
e simplesmente não se importar.
Alguém sabe a sintaxe ou um hack? (Dezenas de linhas via tabelas de definição do MySQL não são realmente um atalho).
Marca de referência:
sem índice = 148,5 segundos
com índice = 180 segundos e ainda rodando com Enviando dados A matriz SSD é tão poderosa que você quase não se importa com o cache de dados...
Definição para benchmark:
CREATE TABLE IF NOT EXISTS `domains_import` (
`domain_id` bigint(20) unsigned NOT NULL,
`domain_name` varchar(253) CHARACTER SET ascii COLLATE ascii_bin NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `domains_import`
ADD PRIMARY KEY (`domain_id`),
ADD UNIQUE KEY `domain_name` (`domain_name`);
ALTER TABLE `domains_import`
MODIFY `domain_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT;
InnoDB, o teste com índice (sem USE INDEX() ou similar) ainda está em execução, 250 segundos, acabei de matá-lo.