Introdução ao banco de dados Postgresql 2-uso

2.1. Introdução

Este capítulo é uma visão geral de como realizar operações simples usando SQL. O objetivo deste tutorial é apenas fornecer uma introdução, não um tutorial SQL completo. Existem muitos livros sobre SQL, incluindo Understanding the New SQL e A Guide to the SQL Standard. O que você precisa saber é que alguns recursos da linguagem PostgreSQL são extensões do padrão.

Nos exemplos a seguir, supomos que você criou um banco de dados denominado mydb, conforme descrito no capítulo anterior, e iniciou o psql.

Os exemplos neste manual também podem ser encontrados no diretório src / tutorial / na distribuição do código-fonte do PostgreSQL (a distribuição binária do PostgreSQL pode não ser capaz de compilar esses arquivos). Para usar esses arquivos, primeiro entre no diretório e depois execute make:

   $ cd ..../src/tutorial
   $ make

Isso cria um script e compila um arquivo C contendo funções e tipos definidos pelo usuário. Para iniciar este tutorial, proceda da seguinte forma:

   $ cd ..../src/tutorial
   $ psql -s mydb
   ...
   mydb=> \i basics.sql

O comando \ i lê os comandos do arquivo especificado. A opção -s do psql coloca você no modo de uma etapa, que fará uma pausa antes de enviar cada instrução ao servidor. Os comandos usados ​​nesta seção estão no arquivo basics.sql

2.2. Conceito

PostgreSQL é um sistema de gerenciamento de banco de dados relacional (RDBMS). Isso significa que é um sistema de gerenciamento de dados que são armazenados de forma relacional. Relacionamento é, na verdade, um termo matemático para tabelas. Hoje, o conceito de armazenamento de dados em tabelas tornou-se um senso comum inerente, mas existem outros métodos para organizar bancos de dados. Arquivos e diretórios em sistemas operacionais do tipo Unix formam um exemplo de banco de dados hierárquico. Um desenvolvimento mais moderno é o banco de dados orientado a objetos.

Cada tabela é um conjunto de linhas nomeadas e cada linha em uma determinada tabela consiste em um conjunto de campos nomeados idênticos. E cada campo é um tipo de dado específico. Embora a posição de cada campo em cada linha seja fixa, é importante lembrar que o SQL não oferece nenhuma garantia sobre a ordem das linhas na tabela (embora sua exibição possa ser claramente classificada).

As tabelas formam um banco de dados e uma série de bancos de dados gerenciados por um determinado servidor PostgreSQL formam um cluster de banco de dados.

2.3. Crie uma nova tabela

Você pode criar uma tabela declarando o nome da tabela e todos os nomes de campo e seus tipos:

   CREATE TABLE weather (
       city            varchar(80),
       temp_lo         int,           -- low temperature
       temp_hi         int,           -- high temperature
       prcp            real,          -- precipitation
       date            date
   );

Você pode inserir esses códigos no psql junto com um caractere de nova linha, e ele pode reconhecer o comando até o ponto-e-vírgula terminar.

Você pode usar livremente espaços em branco (ou seja, espaços, tabulações e novas linhas) em comandos SQL. Isso significa que você pode digitar comandos em um alinhamento diferente do acima e até mesmo escrever todo o código em uma linha. Dois travessões ("-") introduzem comentários. Qualquer coisa que siga até o final da linha será ignorada. O SQL não é sensível ao caso de palavras-chave e identificadores, a menos que o identificador esteja entre aspas duplas para reter seus atributos de caso (não o caso acima).

varchar (80) declara um tipo de dados que pode armazenar qualquer string de até 80 caracteres. int é um tipo inteiro normal. real é um tipo usado para armazenar números de ponto flutuante de precisão simples. O tipo de data deve ser autoexplicativo. (Sim, o nome do campo do tipo data também é data. Isso pode ser mais conveniente ou pode ser confuso - veja você mesmo.)

PostgresSQL suporta os tipos SQL padrão int, smallint, real, double precision, char (N), varchar (N), date, time, timestamp e intervalo, bem como outros tipos comuns e ricos tipos geométricos. O PostgreSQL pode personalizar qualquer número de tipos de dados definidos pelo usuário. Portanto, o nome do tipo não é uma palavra-chave gramatical, exceto para casos especiais exigidos pelo padrão SQL.

O segundo exemplo salvará os nomes das cidades e suas localizações geográficas associadas:

   CREATE TABLE cities (
       name            varchar(80),
       location        point
   );

O tipo de dados do ponto é um exemplo de um tipo de dados exclusivo do PostgreSQL.

Por fim, também mencionaremos que se você não precisar mais de uma tabela ou quiser criar uma tabela diferente, poderá excluí-la com o seguinte comando:

   DROP TABLE tablename;

2.4. Adicionar linhas à tabela

O seguinte comando INSERT é usado para adicionar linhas à tabela:

   INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');

Deve-se observar que todos os tipos de dados usam um formato de entrada bastante claro. Constantes que não são valores numéricos simples devem estar entre aspas simples ('), como no exemplo. O tipo de data é bastante flexível para o formato aceitável, mas neste tutorial, vamos nos ater a um formato de exibição claro aqui.

O tipo de ponto requer um par de coordenadas como entrada, da seguinte maneira:

   INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');

A sintaxe usada até agora requer que você se lembre da ordem dos campos. Uma sintaxe opcional permite que você liste explicitamente os campos:

   INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)
       VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29');

Se precisar, você pode listar os campos em outra ordem ou ignorar alguns campos. Por exemplo, não sabemos a quantidade de precipitação:

       INSERT INTO weather (date, city, temp_hi, temp_lo)
           VALUES ('1994-11-29', 'Hayward', 54, 37);

Muitos desenvolvedores acreditam que é melhor listar os campos explicitamente do que confiar na ordem implícita.

Por favor, digite todos os comandos mostrados acima para que você tenha os dados disponíveis nas seções a seguir.

Você também pode carregar grandes quantidades de dados de arquivos de texto usando o comando COPY. Isso geralmente é mais rápido, porque o comando COPY é otimizado para esse tipo de aplicativo, mas é menos flexível do que INSERT. tal como:

   COPY weather FROM '/home/user/weather.txt';

Aqui, o nome do arquivo de origem deve ser acessível pelo servidor back-end, não pelo cliente, porque o servidor back-end lê o arquivo diretamente. Você pode ler mais sobre o comando COPY na seção COPY.

2.5. Consultar uma tabela

Recuperar dados de uma tabela é, na verdade, consultar essa tabela. O comando SQL SELECT é usado para este propósito. A instrução é dividida em uma lista de seleção (a parte que lista os campos a serem retornados), uma lista de tabela (a parte que lista a tabela da qual os dados são recuperados) e condições opcionais (a parte que declara quaisquer restrições). Por exemplo, para recuperar todas as linhas da tabela de clima, digite:

   SELECT * FROM weather;[1]

Aqui * é a abreviatura de "todas as colunas". O mesmo resultado pode ser obtido pela seguinte consulta:

   SELECT city, temp_lo, temp_hi, prcp, date FROM weather;

E a saída deve ser:

        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27
    San Francisco |      43 |      57 |    0 | 1994-11-29
    Hayward       |      37 |      54 |      | 1994-11-29
   (3 rows)

Você pode escrever expressões arbitrárias na lista de seleção, não apenas referências de coluna. Por exemplo, você pode:

   SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;

Isso deve dar:

        city      | temp_avg |    date
   ---------------+----------+------------
    San Francisco |       48 | 1994-11-27
    San Francisco |       50 | 1994-11-29
    Hayward       |       45 | 1994-11-29
   (3 rows)

Observe como a cláusula AS aqui renomeia a coluna de saída. (A cláusula AS é opcional.)

Uma consulta pode ser "modificada" com a cláusula WHERE para declarar onde a linha é necessária. A cláusula WHERE contém uma expressão booleana (valor de verdade) e somente as linhas em que o valor da expressão booleana é verdadeiro serão retornadas. Operadores booleanos comumente usados ​​(AND, OR e NOT) são permitidos nas condições. Por exemplo, a consulta a seguir recupera o clima em São Francisco em um dia chuvoso:

   SELECT * FROM weather
       WHERE city = 'San Francisco' AND prcp > 0.0;

resultado:

        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27
   (1 row)

Você pode exigir que as consultas retornadas sejam classificadas:

   SELECT * FROM weather
       ORDER BY city;
        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    Hayward       |      37 |      54 |      | 1994-11-29
    San Francisco |      43 |      57 |    0 | 1994-11-29
    San Francisco |      46 |      50 | 0.25 | 1994-11-27

Neste exemplo, a ordem de classificação não é absolutamente clara, então você pode ver a classificação aleatória dos dados da linha para São Francisco. Mas se você usar a seguinte instrução, você sempre obterá o resultado acima

   SELECT * FROM weather
       ORDER BY city, temp_lo;

Você pode usar o seguinte comando para excluir linhas duplicadas no resultado da consulta:

   SELECT DISTINCT city
       FROM weather;
        city
   ---------------
    Hayward
    San Francisco
    (2 rows)

Mais uma vez, a ordem das linhas de resultados pode ser alterada. Você pode combinar DISTINCT e ORDER BY para obter resultados consistentes: [2]

   SELECT DISTINCT city
       FROM weather
       ORDER BY city;

[1] Embora SELECT * seja útil para consultas temporárias, geralmente pensamos que este é um estilo ruim no código de produção, porque adicionar um campo à tabela altera o resultado.

[2] Em alguns sistemas de banco de dados, incluindo versões anteriores do PostgreSQL, a execução de DISTINCT irá classificar as linhas, portanto, ORDER BY é redundante. Mas isso não é um requisito do padrão SQL, e o PostgreSQL atual não garante que DISTINCT fará com que as linhas de dados sejam classificadas.

2.6. Conexão entre tabelas

Até agora, nossa consulta acessou apenas uma tabela por vez. A consulta pode acessar várias tabelas de uma vez ou acessar uma tabela de alguma forma enquanto ainda processa várias linhas de dados na tabela. Chamamos uma consulta que acessa várias linhas de dados na mesma tabela ou em tabelas diferentes ao mesmo tempo que uma consulta de junção. Por exemplo, se você deseja listar todos os registros meteorológicos e as coordenadas das cidades relacionadas a esses registros. Para atingir esse objetivo, precisamos comparar o campo da cidade de cada linha da tabela de clima com o campo de nome de todas as linhas da tabela de cidades e selecionar as linhas que correspondem a esses valores.

Observação: este é apenas um modelo conceitual. Essa conexão geralmente é realizada de uma maneira mais eficiente do que realmente comparar cada par de linhas possível, mas eles são invisíveis para o usuário.

Essa tarefa pode ser realizada com a seguinte consulta:

   SELECT *
       FROM weather, cities
       WHERE city = name;
         city      | temp_lo | temp_hi | prcp |    date    |     name      | location
   ---------------+---------+---------+------+------------+---------------+-----------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
    San Francisco |      43 |      57 |    0 | 1994-11-29 | San Francisco | (-194,53)
   (2 rows)

Observe dois aspectos do conjunto de resultados:

Não há linha de resultado para a cidade Hayward. Isso ocorre porque não há nenhuma linha correspondente de Hayward na tabela de cidades, portanto, a conexão ignora a linha sem correspondência na tabela de clima. Veremos como corrigir esse problema mais tarde.

Dois campos contêm o nome da cidade. Isso é correto porque os campos das tabelas de clima e cidades estão unidos. No entanto, na verdade não queremos isso, então você provavelmente desejará listar explicitamente os campos de saída em vez de usar *:

Exercício: observe a semântica de omitir a cláusula WHERE.

Como cada campo tem um nome diferente, o analisador descobrirá automaticamente a qual tabela eles pertencem. Se houver nomes de campo duplicados nas duas tabelas, você precisará usar nomes de campo qualificados para mostrar qual deles você deseja. A consulta é a seguinte :

   SELECT weather.city, weather.temp_lo, weather.temp_hi,
          weather.prcp, weather.date, cities.location
       FROM weather, cities
       WHERE cities.name = weather.city;

É amplamente considerado um bom estilo limitar todos os nomes de campo em uma consulta de junção, de forma que, mesmo se um nome de coluna duplicado for adicionado a uma das tabelas posteriormente, a consulta não falhará.

Até agora, esse tipo de consulta de junção também pode ser escrito da seguinte forma:

   SELECT *
       FROM weather INNER JOIN cities ON (weather.city = cities.name);

Esta gramática não é tão comumente usada como a anterior, nós a escrevemos aqui para tornar mais fácil para você entender os tópicos que se seguem.

Agora veremos como recuperar os registros de Hayward. O que queremos que a consulta faça é verificar a tabela de clima e encontrar as linhas correspondentes na tabela de cidades para cada linha. Se não encontrarmos uma linha correspondente, precisaremos de alguns "valores vazios" para substituir os campos na tabela de cidades. Esse tipo de consulta é chamado de junção externa. (As conexões que vimos antes são todas conexões internas.) Esse comando tem a seguinte aparência:

   SELECT *
       FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);
        city      | temp_lo | temp_hi | prcp |    date    |     name      | location
   ---------------+---------+---------+------+------------+---------------+-----------
    Hayward       |      37 |      54 |      | 1994-11-29 |               |
    San Francisco |      46 |      50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
    San Francisco |      43 |      57 |    0 | 1994-11-29 | San Francisco | (-194,53)
   (3 rows)

Esta consulta é uma junção externa esquerda, porque as linhas na tabela do lado esquerdo do operador de junção devem aparecer pelo menos uma vez na saída, e as linhas do lado direito produzirão apenas aquelas correspondentes à linha esquerda Linhas correspondentes. Se a linha de saída da tabela à esquerda não corresponder à linha da tabela à direita correspondente, o campo da linha à direita será preenchido com NULL.

Prática; existem conexões corretas e conexões completas. Tente descobrir o que eles fazem.

Também podemos conectar uma mesa a nós mesmos. Isso é chamado de auto-conexão. Por exemplo, suponha que desejamos encontrar registros meteorológicos que estejam dentro da faixa de temperatura de outros registros meteorológicos. Dessa forma, precisamos comparar os campos temp_lo e temp_hi de cada linha na tabela de clima com os campos temp_lo e temp_hi de outras linhas na tabela de clima. Podemos atingir esse objetivo com a seguinte consulta:

   SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,
       W2.city, W2.temp_lo AS low, W2.temp_hi AS high
       FROM weather W1, weather W2
       WHERE W1.temp_lo < W2.temp_lo
       AND W1.temp_hi > W2.temp_hi;
        city      | low | high |     city      | low | high
   ---------------+-----+------+---------------+-----+------
    San Francisco |  43 |   57 | San Francisco |  46 |   50
    Hayward       |  37 |   54 | San Francisco |  46 |   50
   (2 rows)

Aqui, renomeamos a tabela meteorológica como W1 e W2 para distinguir os lados esquerdo e direito da conexão. Você também pode usar esses aliases para salvar alguns pressionamentos de tecla em outras consultas, como:

   SELECT *
       FROM weather w, cities c
       WHERE w.city = c.name;

Freqüentemente, você encontrará essas abreviações no futuro.

2.7. Funções agregadas

Como a maioria dos outros produtos de banco de dados relacional, o PostgreSQL suporta funções agregadas. Uma função de agregação calcula um resultado de várias linhas de entrada. Por exemplo, temos funções de agregação que calculam contagem (número), soma (soma), avg (média), max (máximo) e min (mínimo) em um conjunto de linhas.

Por exemplo, podemos usar a seguinte declaração para encontrar a temperatura mais alta em todos os registros

   SELECT max(temp_lo) FROM weather;
    max
   -----
     46
   (1 row)

Se quisermos saber em qual cidade ocorreu a leitura, podemos usar

SELECT cidade FROM clima WHERE temp_min = max (temp_min); ERRADO

Mas esta consulta não pode ser executada porque a função agregada max não pode ser usada na cláusula WHERE. (Essa restrição existe porque a cláusula WHERE determina quais linhas podem entrar na fase de agregação; portanto, ela deve ser calculada antes que a função de agregação seja executada.) No entanto, geralmente podemos usar outros métodos para atingir nosso objetivo; aqui podemos usar subconsultas:

   SELECT city FROM weather
       WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
        city
   ---------------
    San Francisco
   (1 row)

Isso está certo, porque a subconsulta é um cálculo independente e calcula sua própria agregação, independentemente da consulta externa.

A agregação também é comumente usada em cláusulas GROUP BY. Por exemplo, podemos obter o maior valor de temperatura baixa em cada cidade.

   SELECT city, max(temp_lo)
       FROM weather
       GROUP BY city;
        city      | max
   ---------------+-----
    Hayward       |  37
    San Francisco |  46
   (2 rows)

Isso nos dá uma saída para cada cidade. Cada resultado de agregação é calculado na linha que corresponde à cidade. Podemos filtrar esses grupos com HAVING:

    SELECT city, max(temp_lo)
       FROM weather
       GROUP BY city
       HAVING max(temp_lo) < 40;
     city   | max
   ---------+-----
    Hayward |  37
   (1 row)

Isso fornece apenas as cidades onde o valor temp_lo costumava ter uma temperatura abaixo de 40 graus. Finalmente, se nos preocupamos apenas com as cidades cujos nomes começam com "S", podemos usar

   SELECT city, max(temp_lo)
       FROM weather
       WHERE city LIKE 'S%'(1)
       GROUP BY city
       HAVING max(temp_lo) < 40;

(1) LIKE faz casamento de padrões, conforme explicado na Seção 9.7.

É muito importante para nós entendermos a relação entre agregação e cláusulas SQL WHERE e HAVING. A diferença básica entre WHERE e HAVING é a seguinte: WHERE seleciona linhas de entrada antes dos cálculos de agrupamento e agregação (portanto, ele controla quais linhas entram no cálculo de agregação), enquanto HAVING seleciona linhas agrupadas após agrupamento e agregação. Portanto, a cláusula WHERE não pode conter funções de agregação; não faz sentido tentar usar funções de agregação para determinar quais linhas são inseridas nas operações de agregação. Em contraste, a cláusula HAVING sempre contém funções agregadas. (Estritamente falando, você pode escrever uma cláusula HAVING que não use agregação, mas isso raramente é útil. As mesmas condições podem ser usadas de maneira mais eficaz na fase WHERE.)

No exemplo anterior, podemos aplicar a restrição do nome da cidade em WHERE porque ela não requer agregação. Isso é mais eficiente do que aumentar o limite em HAVING, porque evitamos cálculos de agrupamento e agregação para linhas que falham na verificação WHERE.

2.8. Atualização

Você pode atualizar as linhas existentes com o comando UPDATE. Suponha que você descubra que todas as contagens de temperatura em 28 de novembro estão dois graus mais baixas, então você pode atualizar os dados da seguinte maneira:

   UPDATE weather
       SET temp_hi = temp_hi - 2,  temp_lo = temp_lo - 2
       WHERE date > '1994-11-28';

Observe o novo estado dos dados:

   SELECT * FROM weather;
        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27
    San Francisco |      41 |      55 |    0 | 1994-11-29
    Hayward       |      35 |      52 |      | 1994-11-29
   (3 rows)

2.9. Excluir

As linhas de dados podem ser excluídas da tabela com o comando DELETE. Supondo que você não esteja mais interessado no clima de Hayward, você pode excluir essas linhas da tabela da seguinte maneira:

   DELETE FROM weather WHERE city = 'Hayward';所有属于Hayward的天气记录都将被删除。 
   SELECT * FROM weather;
        city      | temp_lo | temp_hi | prcp |    date
   ---------------+---------+---------+------+------------
    San Francisco |      46 |      50 | 0.25 | 1994-11-27
    San Francisco |      41 |      55 |    0 | 1994-11-29
   (2 rows)

Devemos ter cuidado ao usar declarações da seguinte forma

   DELETE FROM tablename;

Se não houver nenhuma condição, DELETE excluirá todas as linhas da tabela especificada e as apagará. O sistema não pedirá sua confirmação antes de fazer isso!

Acho que você gosta

Origin blog.csdn.net/qq_37061368/article/details/112978506
Recomendado
Clasificación