Linguagem de definição de dados

Use a linguagem de definição de dados (DDL, na sigla em inglês) do Cloud Spanner para:

  • criar um banco de dados;
  • criar, alterar ou remover tabelas em um banco de dados;
  • adicionar, alterar ou soltar colunas em uma tabela;
  • criar ou soltar índices em um banco de dados.

Sintaxe DDL

statement:
    { create_database | alter_database | create_table | create_index | alter_table | drop_table | drop_index }

create_database:
    CREATE DATABASE database_id

alter_database:
    ALTER DATABASE database_id
    action

where action is:
    SET OPTIONS ( optimizer_version = { 1 ... 2 | null } )

create_table:
    CREATE TABLE ( [
       { column_name data_type [NOT NULL] [ options_def]
       | table_constraint }
       [, ... ]
    ] ) PRIMARY KEY ( [ column_name [ { ASC | DESC } ], ...] )
    [INTERLEAVE IN PARENT table_name [ ON DELETE { CASCADE | NO ACTION } ] ]

    where data_type is:
        { scalar_type | array_type }

    and options_def is:
        { OPTIONS ( allow_commit_timestamp = { true | null } ) }

    and table_constraint is:
        [ CONSTRAINT constraint_name ]
        { FOREIGN KEY ( column_name [, ... ] ) REFERENCES ref_table ( ref_column [, ... ] ) }

create_index:
    CREATE [ UNIQUE ] [ NULL_FILTERED ] INDEX index_name
    ON table_name ( key_part [, ...] ) [ storing_clause ] [ , interleave_clause ]

    where index_name is:
        {a—z|A—Z}[{a—z|A—Z|0—9|_}+]

    and key_part is:
        column_name [ { ASC | DESC } ]

    and storing_clause is:
        STORING ( column_name [, ...] )

    and interleave_clause is:
        INTERLEAVE IN table_name

alter_table:
    ALTER TABLE table_name
    action [, ... ]

    where action is:
        ADD [ COLUMN ] column_name data_type [ NOT NULL ] [ options_def ]
        DROP [ COLUMN ] column_name
        ADD table_constraint
        DROP CONSTRAINT constraint_name
        SET ON DELETE { CASCADE | NO ACTION }
        ALTER [ COLUMN ] column_name { { data_type } [ NOT NULL ] | SET [ options_def ] }

    and data_type is:
        { scalar_type | array_type }

    and options_def is:
        { OPTIONS ( allow_commit_timestamp = { true | null } ) }

    and table_constraint is:
        [ CONSTRAINT constraint_name ]
        { FOREIGN KEY ( column_name [, ... ] ) REFERENCES ref_table ( ref_column [, ... ] ) }

drop_table:
    DROP TABLE table_name

drop_index:
    DROP INDEX index_name

scalar_type:
    { BOOL | INT64 | FLOAT64 | STRING( length ) | BYTES( length ) | DATE | TIMESTAMP }

length:
    { int64_value | MAX }

array_type:
    ARRAY< scalar_type >

int64_value:
    { decimal_value | hex_value }

decimal_value:
    [-]0—9+

hex_value:
    [-]0x{0—9|a—f|A—F}+

database_id:
    {a—z}[{a—z|0—9|_|-}+]{a—z|0—9}

table_name, column_name, index_name:
    {a—z|A—Z}[{a—z|A—Z|0—9|_}+]

Notação:

  • Os colchetes "[ ]" indicam cláusulas opcionais.
  • Os parênteses "( )" indicam parênteses literais.
  • A barra vertical "|" indica um operador lógico "OR".
  • Chaves "{ }" delimitam um conjunto de opções.
  • Uma vírgula seguida por reticências indica que o item anterior pode se repetir em uma lista separada por vírgulas. item [, ...] indica um ou mais itens, e [item, ...] indica zero ou mais itens.
  • Uma vírgula "," indica a vírgula literal.
  • Colchetes angulares "<>" indicam colchetes angulares literais.
  • Um mdash "—" indica uma gama de valores entre os itens de cada lado.
  • O sinal de adição "+" indica que o item anterior pode se repetir.

Palavras-chave reservadas

Algumas palavras, como nomes de tipo, são reservadas na DDL do Cloud Spanner. Se você precisar usar uma palavra-chave reservada como um identificador em seu esquema, coloque-a entre acentos graves (`). Para obter a lista completa de palavras-chave reservadas no Cloud Spanner, consulte Estrutura e sintaxe léxicas.

Exemplo:

CREATE TABLE MyTable (
  RowId INT64 NOT NULL,
  `Int64` INT64
) PRIMARY KEY (RowId);

Convenções de nomeação

As regras a seguir se aplicam a nomes de restrições de tabela, coluna, índice e chave externa.

  • podem ter entre 1 e 128 caracteres;

  • precisam começar com uma letra maiúscula ou minúscula;

  • podem conter letras maiúsculas e minúsculas, números e sublinhados, mas não hifens;

  • Não é possível criar dois objetos do Cloud Spanner com o mesmo nome. Isso inclui nomes que diferem apenas em letras maiúsculas. Por exemplo, a segunda instrução no snippet a seguir falha porque os nomes das tabelas diferem apenas nas letras maiúsculas e minúsculas.

    CREATE TABLE MyTable (col1 INT64) PRIMARY KEY (col1);
    CREATE TABLE MYTABLE (col1 INT64) PRIMARY KEY (col1);
    
  • Ao fazer referência a outros objetos de esquema em uma instrução DDL (por exemplo, um nome de coluna para uma chave primária ou nomes de tabela e coluna em um índice), use as letras maiúsculas ou minúsculas conforme o original no nome de cada entidade. Como exemplo, considere a tabela Singers criada com a instrução a seguir.

    CREATE TABLE Singers (
      SingerId   INT64 NOT NULL,
      FirstName  STRING(1024),
      LastName   STRING(1024),
      SingerInfo BYTES(MAX),
      BirthDate  DATE,
    ) PRIMARY KEY(SingerId);
    

    O comando a seguir falha com a mensagem Table not found: singers porque há uma letra maiúscula a mais na tabela Singers.

    CREATE INDEX SingersByFirstLastName ON singers(FirstName, LastName)
    
  • Os nomes de objeto do esquema do Cloud Spanner não diferenciam maiúsculas de minúsculas em consultas SQL. Como exemplo, considere a tabela MyTable2 criada com a instrução a seguir.

    CREATE TABLE MyTable2 (col1 INT64) PRIMARY KEY (col1);
    

    Todas as consultas a seguir são bem-sucedidas porque os nomes de objeto do esquema não diferenciam maiúsculas de minúsculas.

    SELECT col1 FROM MyTable2 LIMIT 1
    SELECT COL1 FROM MYTABLE2 LIMIT 1
    SELECT COL1 FROM mytable2 LIMIT 1
    INSERT INTO MYTABLE2 (col1) VALUES(1)
    

Instruções DATABASE

CREATE DATABASE

Ao criar um banco de dados do Cloud Spanner, você deve fornecer uma instrução CREATE DATABASE, que define o código do banco de dados:

CREATE DATABASE database_id

where database_id
    {a—z}[{a—z|0—9|_|-}+]{a—z|0—9}

Parâmetros

database_id

ALTER DATABASE

Altera a definição de uma tabela.

Sintaxe

ALTER DATABASE database_id
    action

where database_id is:
    {a—z}[{a—z|0—9|_|-}+]{a—z|0—9}

and action is:
    SET OPTIONS ( optimizer_version = { 1 ...  2 | null } )

Descrição

ALTER DATABASE altera a definição de um banco de dados existente.

SET OPTIONS

  • Use essa cláusula para definir uma opção no nível do banco de dados da hierarquia do esquema.

Parâmetros

database_id

  • O nome do banco de dados cujos atributos serão alterados. Se o nome for uma palavra reservada ou contiver um hífen, coloque-o entre acentos graves (`). Para mais informações sobre convenções de nomenclatura de banco de dados, consulte convenções de nomenclatura neste documento.

options_def

  • A opção ( optimizer_version = { 1 ... 2 | null } ) permite especificar a versão do otimizador de consultas a ser usada. Por padrão, essa é a versão mais recente do otimizador, mas você pode especificar qualquer versão disponível. Definir essa opção como null equivale a defini-la para a versão mais recente, que atualmente é a 2. Para mais informações, consulte Otimizador de consultas.

Tipos de dados

Escalares

A sintaxe para usar um tipo escalar em DDL é:

{ BOOL | INT64 | FLOAT64 | STRING( length ) | BYTES( length ) | DATE | TIMESTAMP }

length:
    { int64_value | MAX }

int64_value:
    { decimal_value | hex_value }

decimal_value:
    [-]0—9+

hex_value:
    [-]0x{0—9|a—f|A—F}+

Um int64_value deve corresponder a um número inteiro de -9.223.372.036.854.775.808 (-2 63) a 9.223.372.036.854.775.807 (2 63 - 1). Ele pode ser especificado com notação decimal ou hexadecimal. O formato hexadecimal requer um prefixo 0x, com um x minúsculo.

STRING

STRING é uma sequência de caracteres Unicode de comprimento variável. Seu valor precisa ser uma string Unicode válida. O comprimento é necessário e representa o número máximo de caracteres Unicode (não bytes) que podem ser armazenados no campo.

Observações:

  • As gravações na coluna são validadas e serão rejeitadas se o novo valor não for uma string Unicode válida ou exceder o comprimento especificado.

  • length pode ser um número inteiro no intervalo [1, 2621440] (2,5 MB).

  • Para um campo cujo comprimento é imprevisível ou não precisa ser limitado, é possível definir length para o valor de conveniência MAX, que é equivalente a 2621440 para fins de validação.

    Apenas o comprimento real da string armazenada afeta os custos de armazenamento. O uso de MAX não consome nenhuma capacidade de armazenamento adicional.

  • O Cloud Spanner requer que as strings Unicode sejam codificadas em UTF-8 no recebimento no servidor.

  • A compilação é feita pelo valor numérico do caractere Unicode, tecnicamente por ponto de código, que é sutilmente diferente devido à combinação de caracteres. Para strings ASCII, esta é a ordem de classificação tradicional.

  • É possível reduzir o comprimento de uma coluna depois que a tabela foi criada, mas para isso o Cloud Spanner terá que validar que os dados atuais obedecem à restrição de comprimento.

BYTES

BYTES é uma string binária de comprimento variável. O comprimento é necessário e representa o número máximo de bytes que podem ser armazenados no campo.

Observações:

  • As gravações na coluna são validadas e serão rejeitadas se o novo valor exceder o comprimento especificado.

  • length pode ser um número inteiro no intervalo [1, 10485760] (10 MB) ou o valor de conveniência MAX, que é equivalente a 10485760 para fins de validação.

    Apenas os bytes armazenados reais afetam os custos de armazenamento. O uso de MAX não consome nenhuma capacidade de armazenamento adicional.

  • É possível reduzir o comprimento de uma coluna depois que a tabela foi criada, mas para isso o Cloud Spanner terá que validar que os dados atuais obedecem à restrição de comprimento.

DATE

  • Uma data independente do fuso horário.
  • O intervalo [0001-01-01, 9999-12-31] é o intervalo legal para datas. Uma gravação à uma coluna de data será rejeitada se o valor estiver fora desse intervalo.
  • Consulte mais informações e o formato canônico em Tipos de dados.

TIMESTAMP

  • Um carimbo de data/hora com precisão de nanossegundos.
  • Independente do fuso horário, na faixa [0001-01-01 00:00:00 a 10000-01-01 00:00:00).
  • Consulte mais informações e o formato canônico em Tipos de dados.

Matrizes

A sintaxe para usar o tipo ARRAY em DDL é:

ARRAY< scalar_type >

O Cloud Spanner aceita matrizes de escalares. O objetivo principal de matrizes é armazenar uma coleção de valores em um espaço de maneira eficiente. As matrizes não foram criadas para fornecer acesso a elementos individuais; para ler ou gravar um único elemento, você deve ler ou gravar toda a matriz.

Se seu aplicativo usar estruturas de dados como vetores ou campos repetidos, é possível manter o estado deles em uma matriz do Cloud Spanner.

Veja um exemplo de uma definição alternativa de Singers que usa várias colunas do tipo ARRAY:

CREATE TABLE Singers (
  SingerId INT64,
  FeaturedSingerIds ARRAY<INT64>,
  SongNames ARRAY<STRING(MAX)>,
) PRIMARY KEY (SingerId) ...;

Observações:

  • Matrizes com subtipo ARRAY (matrizes aninhadas) não são aceitas.
  • Matrizes, como valores escalares, jamais podem ultrapassar 10 MiB no total.
  • Matrizes não podem ser usadas como colunas de chave.
  • Em uma instrução CREATE TABLE, é possível criar colunas do tipo ARRAY com uma anotação NOT NULL.

    Depois de criar a tabela, não será possível adicionar uma coluna do tipo ARRAY com uma anotação NOT NULL nem será possível adicionar uma anotação NOT NULL a uma coluna existente do tipo ARRAY.

Instruções TABLE

CREATE TABLE

Define uma nova tabela.

Sintaxe

CREATE TABLE table_name ( [
   { column_name data_type [ NOT NULL ] [ options_def ]
   | table_constraint }
   [, ... ]
] ) PRIMARY KEY ( [column_name [ { ASC | DESC } ], ...] )
[INTERLEAVE IN PARENT table_name [ ON DELETE { CASCADE | NO ACTION } ] ]

where data_type is:
    { scalar_type | array_type }

and options_def is:
    { OPTIONS ( allow_commit_timestamp = { true | null } ) }

and table_constraint is:
    [ CONSTRAINT constraint_name ]
    { FOREIGN KEY ( column_name [, ... ] ) REFERENCES  ref_table  ( ref_column [, ... ] ) }

Descrição

CREATE TABLE define uma nova tabela no banco de dados atual.

Parâmetros

table_name

column_name

data_type

  • O tipo de dados da coluna, que pode ser um tipo Escalar ou uma Matriz.

NOT NULL

  • Essa anotação de coluna opcional especifica que a coluna é obrigatória em todas as mutações que inserem uma nova linha.

  • Não é possível adicionar uma coluna NOT NULL a uma tabela atual. Para a maioria dos tipos de coluna, é possível contornar essa limitação:

    • Para colunas do tipo ARRAY, a única vez que você pode usar uma anotação NOT NULL é quando você cria a tabela. Depois disso, não será possível adicionar uma anotação NOT NULL a uma coluna do tipo ARRAY.

    • Para todos os outros tipos de coluna, você pode adicionar uma coluna anulável. Preencha essa coluna gravando valores em todas as linhas e atualize seu esquema com uma anotação NOT NULL nessa coluna.

PRIMARY KEY ( [column_name[ { ASC | DESC } ], ...]

  • Toda tabela precisa ter uma chave primária, e essa chave pode ser composta por zero ou mais colunas da tabela.

  • Adicionar a anotação DESC em um nome de coluna de chave primária altera o layout físico de dados de ordem ascendente (padrão) para ordem decrescente.

    Para mais detalhes, consulte Esquema e modelo de dados.

[INTERLEAVE IN PARENTtable_name[ ON DELETE { CASCADE | NO ACTION } ] ]

  • Essa cláusula define um relacionamento de tabela filha para pai, o que resulta em uma intercalação física de linhas pai e filho. As colunas de chave primária de um pai precisam ser correspondentes em termos de posição, em nome e tipo, a um prefixo das colunas de chave primária de qualquer filho. Adicionar linhas à tabela filho falhará se a linha pai correspondente não existir. A linha pai pode já existir no banco de dados ou pode ser inserida antes da inserção das linhas filho na mesma transação.

  • A instrução ON DELETE opcional define o comportamento de linhas em ChildTable quando uma mutação tenta excluir a linha pai. Veja a seguir as opções aceitas:

    • CASCADE: as linhas filho são excluídas.

    • NO ACTION: as linhas filho não são excluídas. Se a exclusão de um pai deixar linhas filho para trás, o que viola a integridade referencial pai-filho, a gravação falhará.

    É possível omitir a instrução ON DELETE, caso em que o padrão de ON DELETE NO ACTION é usado.

    Para mais detalhes, consulte Esquema e modelo de dados.

CONSTRAINTconstraint_name

  • Um nome opcional para uma restrição de tabela. Se um nome não for especificado, o Cloud Spanner gerará um nome para a restrição. Nomes de restrições, incluindo nomes gerados, podem ser consultados no esquema de informações do Cloud Spanner.

FOREIGN KEY (column_name[, ... ] ) REFERENCESref_table(ref_column[, ... ] )

  • Use essa cláusula para definir uma restrição de chave externa. Uma chave externa é definida na tabela de referência do relacionamento e faz referência à tabela referenciada. As colunas de chave externa das duas tabelas são chamadas de colunas de referência e referenciadas, e os valores de linha são as chaves.

  • Uma restrição de chave externa exige que uma ou mais colunas dessa tabela só possam conter valores que estejam nas colunas referenciadas da tabela referenciada.

  • Ao criar uma chave externa, uma restrição exclusiva é criada automaticamente na tabela referenciada, a menos que toda a chave primária seja referenciada. Se a restrição exclusiva não puder ser atendida, toda a alteração do esquema falhará.

  • O número de colunas de referência e referenciadas precisa ser o mesmo. O pedido também é significativo. Ou seja, a primeira coluna de referência se refere à primeira coluna referenciada, a segunda se refere à segunda e assim por diante.

  • As colunas de referência e referenciadas precisam ter tipos correspondentes e devem ser compatíveis com o operador de igualdade ('='). As colunas também precisam ser indexáveis. Colunas do tipo ARRAY não são permitidas.

  • Não é possível criar chaves externas em colunas com a opção allow_commit_timestamp=true.

    Para detalhes, consulte Chaves externas.

OPTIONS ( allow_commit_timestamp = { true | null } )

  • A opção allow_commit_timestamp permite inserir e atualizar operações para solicitar que o Cloud Spanner grave o carimbo de data/hora de confirmação da transação na coluna. Para detalhes, consulte Carimbos de data/hora de confirmação.

ALTER TABLE

Altera a definição de uma tabela.

Sintaxe

ALTER TABLE table_name
    action [, ... ]

where action is:
    ADD COLUMN column_name data_type [ NOT NULL]  [ options_def ]
    DROP COLUMN column_name
    ADD table_constraint
    DROP CONSTRAINT constraint_name
    SET ON DELETE { CASCADE | NO ACTION }
    ALTER COLUMN column_name { { data_type } [ NOT NULL ] | SET [ options_def ] }

and data_type is:
    { scalar_type | array_type }

and options_def is:
    { OPTIONS (allow_commit_timestamp = { true | null } ) }

and table_constraint is:
    [ CONSTRAINT constraint_name ]
    { FOREIGN KEY ( column_name [, ... ] ) REFERENCES ref_table ( ref_column [, ... ] ) }

Descrição

ALTER TABLE altera a definição de uma tabela existente.

ADD COLUMN

  • Adiciona uma nova coluna à tabela, usando a mesma sintaxe de CREATE TABLE.

DROP COLUMN

  • Descarta uma coluna de uma tabela.

ADDtable_constraint

  • Adiciona uma nova restrição a uma tabela usando a mesma sintaxe de CREATE TABLE. Para chaves externas, os dados existentes são validados antes que a chave externa seja adicionada. Se alguma chave restrita existente não tiver uma chave referenciada correspondente ou a chave referenciada não for exclusiva, a restrição estará em violação e a instrução ALTER falhará.

DROP CONSTRAINTconstraint_name

  • Descarta a restrição especificada em uma tabela, juntamente com qualquer índice associado.

SET ON DELETE { CASCADE | NO ACTION }

  • Essa alteração só pode ser aplicada em tabelas filhas de relações pai-filho, ou seja, tabelas intercaladas. Para mais informações, consulte Esquema e modelo de dados.

  • A cláusula ON DELETE CASCADE significa que, quando uma linha da tabela pai é excluída, as linhas filhas nessa tabela também são excluídas automaticamente. Linhas filhas são todas as linhas que começam com a mesma chave primária. Se uma tabela filha não tiver essa anotação ou se a anotação for ON DELETE NO ACTION, exclua as linhas filhas antes de excluir a linha mãe.

ALTER COLUMN

  • Altera a definição de uma coluna existente em uma tabela.

Parâmetros

table_name

  • O nome de uma tabela existente a ser alterada.

column_name

  • O nome de uma coluna nova ou existente. Não é possível alterar as colunas de chave de uma tabela.

data_type

  • Tipo de dados da nova coluna ou novo tipo de dados de uma coluna existente.

options_def

  • A opção (allow_commit_timestamp=true) permite inserir e atualizar operações para solicitar que o Cloud Spanner grave o carimbo de data/hora de confirmação da transação na coluna. Para detalhes, consulte Carimbos de data/hora de confirmação.

table_constraint

  • Nova restrição de tabela da tabela.

constraint_name

  • O nome de uma restrição nova ou existente.

ref_table

  • A tabela referenciada em uma restrição de chave externa.

ref_column

  • A coluna referenciada em uma restrição de chave externa.

DROP TABLE

Remove uma tabela.

Sintaxe

DROP TABLE table_name

Descrição

Use a instrução DROP TABLE para remover uma tabela do banco de dados.

  • DROP TABLE não é recuperável.

  • Não é possível descartar uma tabela se houver índices sobre ela ou se houver tabelas ou índices intercalados nela.

  • Uma instrução DROP TABLE descarta automaticamente as chaves externas da tabela e os índices de backup de chaves externas.

Parâmetros

table_name

  • O nome da tabela a ser descartada.

Instruções INDEX

CREATE INDEX

Use a instrução CREATE INDEX para definir índices secundários.

Sintaxe

CREATE [ UNIQUE ] [ NULL_FILTERED ] INDEX index_name
ON table_name ( key_part [, ...] ) [ storing_clause ] [ , interleave_clause ]

where index_name is:
    {a—z|A—Z}[{a—z|A—Z|0—9|_}+]

and key_part is:
    column_name [ { ASC | DESC } ]

and storing_clause is:
    STORING ( column_name [, ...] )

and interleave_clause is:
    INTERLEAVE IN table_name

Descrição

O Cloud Spanner indexa automaticamente as colunas de chave primária de cada tabela.

Você pode usar CREATE INDEX para criar índices secundários para outras colunas. Adicionar um índice secundário a uma coluna torna mais eficiente a procura de dados nessa coluna. Para mais detalhes, consulte índices secundários.

Parâmetros

UNIQUE

  • Indica que esse índice secundário impõe uma restrição UNIQUE aos dados que estão sendo indexados. A restrição UNIQUE causa a rejeição de qualquer transação que resultaria em uma chave de índice duplicada. Consulte Índices exclusivos para mais informações.

NULL_FILTERED

index_name

table_name

  • O nome da tabela a ser indexada.

INTERLEAVE IN

  • Define uma tabela para intercalar o índice. Se T é a tabela na qual o índice é intercalado, então:

    • T precisa ser um pai da tabela sendo indexada; e
    • a chave primária de T precisa ser o prefixo de chave do índice.

    Quando é preciso criar um índice intercalado? Se a chave de índice que você pretende usar para operações de índice corresponde à chave de uma tabela, pense em intercalar o índice nessa tabela caso a linha na tabela tenha uma relação de localidade de dados com as linhas indexadas correspondentes.

    Por exemplo, se você quiser indexar todas as linhas de Songs para uma linha específica de Singers, suas chaves de índice conteriam SingerId e SongName e seu índice seria um bom candidato para intercalar Singers se você costuma buscar informações sobre um cantor enquanto busca as músicas do cantor no índice. A definição de SongsBySingerSongName em Como um índice secundário é um exemplo de como criar um índice intercalado.

    Como tabelas entrelaçadas, as entradas em índices entrelaçados são armazenadas com a linha correspondente da tabela pai. Consulte Divisões do banco de dados para ver mais detalhes.

DESC

  • Define ordem de verificação decrescente para a coluna de índice correspondente. Ao verificar uma tabela usando uma coluna de índice marcada com DESC, as linhas verificadas aparecem na ordem decrescente em relação a essa coluna de índice. Se você não especificar uma ordem de classificação, o padrão é crescente (ASC).

STORING

  • Fornece um mecanismo para duplicar dados da tabela em um ou mais índices secundários nessa tabela. Ao custo de armazenamento extra, isso pode reduzir a latência de leitura ao pesquisar dados usando um índice secundário, já que elimina a necessidade de recuperar dados da tabela principal depois de ter encontrado as entradas esperadas no índice. Consulte a cláusula STORING para um exemplo.

DROP INDEX

Remove um índice secundário.

Sintaxe

DROP INDEX index_name

Descrição

Use a instrução DROP INDEX para descartar um índice secundário.

Parâmetros

index_name

  • O nome do índice a ser descartado.

As regras a seguir se aplicam aos IDs do banco de dados.

  • Precisa começar com uma letra minúscula.
  • podem conter letras minúsculas, números, sublinhados e hifens, mas não letras maiúsculas;
  • não podem terminar com um sublinhado ou hífen;
  • precisam estar entre acentos graves (``) se for uma palavra reservada ou incluir um hífen;
  • podem ter entre 2 e 30 caracteres;
  • não podem ser alterados depois de criados.