AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 239539
Accepted
GWR
GWR
Asked: 2019-06-01 02:11:01 +0800 CST2019-06-01 02:11:01 +0800 CST 2019-06-01 02:11:01 +0800 CST

MySQL Case Sensitive Join no Varchar

  • 772

Eu tenho duas tabelas, ambas com tipos de dados idênticos, conjuntos de caracteres e agrupamento explicitamente especificados.

CLERK CHAR(3) CHARACTER SET latin1 COLLATE latin1_bin NULL

Para uma junção que diferencia maiúsculas de minúsculas no CLERKcampo, preciso especificar a ordenação na cláusula de junção também ou o fato de ela ser especificada no nível DDL significa que ela não é necessária na junção?

FROM
    CUSTOMER S JOIN 
    CLERK C ON S.CLERK = C.CLERK COLLATE latin1_bin
mysql mysql-5.7
  • 1 1 respostas
  • 1704 Views

1 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2019-06-01T08:59:40+08:002019-06-01T08:59:40+08:00

    Para uma junção que diferencia maiúsculas de minúsculas no CLERKcampo, preciso especificar a ordenação na cláusula de junção também ou o fato de ela ser especificada no nível DDL significa que ela não é necessária na junção?

    Resposta simples: Não há necessidade de especificar o agrupamento na consulta. O agrupamento de nível DDL (especialmente quando é o mesmo em ambos os lados e ambos os lados são colunas) será usado (e é por isso que o especificamos no nível DDL em primeiro lugar).


    Resposta detalhada: existe uma hierarquia de precedência para qual colação usar em uma determinada operação (concatenação, predicado, etc). O agrupamento usado não depende apenas de ser uma coluna versus um literal, etc., mas também se é Unicode versus não Unicode e até binário versus não binário. A descrição completa pode ser encontrada aqui, Collation Coercibility in Expressions , que é a documentação do MySQL 5.7 já que você está usando essa versão. Uma regra bastante interessante é:

    Para uma operação com operandos do mesmo conjunto de caracteres, mas que misturam uma _binordenação e a _ciou _csordenação, a _binordenação é usada. Isso é semelhante a como as operações que misturam strings não binárias e binárias avaliam os operandos como strings binárias, exceto que é para agrupamentos em vez de tipos de dados.

    Dito tudo isso, preciso ressaltar que a declaração "os agrupamentos binários diferenciam maiúsculas de minúsculas", embora extremamente comum, é definitivamente incorreta.

    1. Em um nível muito básico, a classificação é diferente. Os agrupamentos que diferenciam maiúsculas de minúsculas classificarão "a" com "A" (embora o que vem primeiro pode depender da cultura), "b" com "B" e assim por diante. Os agrupamentos binários serão classificados de acordo com o valor subjacente/ponto de código de cada caractere, o que se torna muito aparente quando as versões maiúsculas e minúsculas de um caractere são separadas por outras de acordo com seu valor.

    2. Ser "sensível a maiúsculas" significa que você também pode ser "INsensível" a outras propriedades de caracteres, sendo a principal acentos. Essa também é a única outra propriedade quando se trata de conjuntos de caracteres não Unicode, mas o Unicode permite a sensibilidade do tipo Kana, a sensibilidade da largura e o SQL Server (a partir da versão 2017) permite até a sensibilidade do seletor de variação. Os agrupamentos binários não permitem que um caractere seja igual a nada além de si mesmo, mesmo que existam outras formas dele. Novamente, isso não acontece muito em conjuntos de caracteres não Unicode, mas em Unicode pode haver várias versões de um caractere, incluindo amplo, sobrescrito, subscrito, itálico, de cabeça para baixo (referido como "virado"), etc. . MySQL, começando na versão 8.0 (até onde eu sei),ut8mb4conjunto de caracteres e agrupamentos):

      • Novos agrupamentos no MySQL 8.0.0 (insensibilização de acento e maiúsculas e minúsculas)
      • MySQL 8.0.1: ordenações de acentuação e maiúsculas e minúsculas para utf8mb4 (acento e maiúsculas)
      • A versão do MySQL 8.0.2 Milestone está disponível (diferenciando acentos, diferenciando maiúsculas de minúsculas)

    Para ilustrar esses dois pontos, configurei uma demonstração no incrível db<>fiddle . Eu tive que usar o MySQL 8.0 não apenas para obter o _ai_ciagrupamento, mas também porque a COLLATE latin1_general_cicláusula (2ª à última consulta, #5) não teve nenhum efeito (por algum motivo estranho; a documentação afirma que quando o nome do agrupamento tem apenas _ci, então _aiestá implícito, ainda para MySQL 5.6 e 5.7 em db<>fiddle , o comportamento ainda é _as_csou _bin).

    E há ainda outras maneiras pelas quais os agrupamentos binários não diferenciam maiúsculas de minúsculas. Não podem contabilizar:

    • combinando diacríticos
    • expansões
    • contrações

    Eu não listei ou forneci exemplos para eles anteriormente porque eles não pertencem a codificações de 8 bits e latin1são uma codificação de 8 bits. Esses são recursos do Unicode e, portanto, devem ser aplicados a qualquer agrupamento Unicode (embora eu não os tenha testado no MySQL, mas eles são implementados corretamente no SQL Server).

    PS Eu tenho uma explicação detalhada de tudo isso (incluindo os comportamentos específicos do Unicode observados diretamente acima) no seguinte post: Não, os agrupamentos binários não são sensíveis a maiúsculas e minúsculas . Atualmente, isso está enquadrado apenas no contexto do SQL Server, mas posso trabalhar no exemplo que criei para essa resposta quando tiver tempo. O importante é que o conceito seja o mesmo em todos os RDBMSs.


    Para referência (caso db<>fiddle esteja inacessível), as consultas são:

    Consulta 1

    CREATE TABLE CLERK (
      CLERK_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      CLERK CHAR(3) CHARACTER SET latin1 COLLATE latin1_bin NULL
    );
    
    CREATE TABLE CUSTOMER (
      CUSTOMER_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      NAME VARCHAR(10) NOT NULL,
      CLERK CHAR(3) CHARACTER SET latin1 COLLATE latin1_bin NULL,
      CLERK_CI_AI CHAR(3) CHARACTER SET latin1 COLLATE latin1_general_ci NULL
    );
    
    INSERT INTO CUSTOMER (NAME, CLERK, CLERK_CI_AI) VALUES('John Doe', 'Ü', 'Ü');
    
    INSERT INTO CLERK (CLERK) VALUES('Ü');
    INSERT INTO CLERK (CLERK) VALUES('ü');
    INSERT INTO CLERK (CLERK) VALUES('U');
    INSERT INTO CLERK (CLERK) VALUES('u');
    INSERT INTO CLERK (CLERK) VALUES('Ù');
    INSERT INTO CLERK (CLERK) VALUES('ù');
    INSERT INTO CLERK (CLERK) VALUES('Û');
    INSERT INTO CLERK (CLERK) VALUES('û');
    
    INSERT INTO CLERK (CLERK) VALUES('Y');
    INSERT INTO CLERK (CLERK) VALUES('y');
    INSERT INTO CLERK (CLERK) VALUES('Ý');
    INSERT INTO CLERK (CLERK) VALUES('ý');
    

    Consulta 2

    SELECT 0 AS "ver", C.*
    FROM   CLERK C;
    

    Consulta 3

    SELECT "bin sort" AS "ver", C.*
    FROM   CLERK C
    ORDER BY C.CLERK;
    

    Consulta 4

    SELECT "cs sort" AS "ver", C.*
    FROM   CLERK C
    ORDER BY C.CLERK COLLATE latin1_general_cs;
    

    Consulta 5

    SELECT 1 AS "ver", S.*, C.*
    FROM CUSTOMER S
    JOIN CLERK C
      ON S.CLERK = C.CLERK;
    

    Consulta 6

    SELECT 2 AS "ver", S.*, C.*
    FROM CUSTOMER S
    JOIN CLERK C
      ON S.CLERK = C.CLERK COLLATE latin1_bin;
    

    Consulta 7

    SELECT 3 AS "ver", S.*, C.*
    FROM CUSTOMER S
    JOIN CLERK C
      ON S.CLERK_CI_AI = C.CLERK;
    

    Consulta 8

    SELECT 4 AS "ver", S.*, C.*
    FROM CUSTOMER S
    JOIN CLERK C
      ON S.CLERK_CI_AI = C.CLERK COLLATE latin1_bin;
    

    Consulta 9

    # is accent-sensitive even though documentation states it should be
    # accent-INsensitive
    # 
    SELECT 5 AS "ver", S.*, C.*
    FROM CUSTOMER S
    JOIN CLERK C
      ON S.CLERK_CI_AI = C.CLERK COLLATE latin1_general_ci;
    

    Consulta 10

    SELECT 6 AS "ver", S.*, C.*
    FROM CUSTOMER S
    JOIN CLERK C
      ON CONVERT(S.CLERK_CI_AI using utf8mb4)
           = CONVERT(C.CLERK USING utf8mb4) COLLATE utf8mb4_general_ci;
    
    • 3

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve