Clipper On Line • Ver Tópico - Base de dados, códigos, etc.

Base de dados, códigos, etc.

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

 

Base de dados, códigos, etc.

Mensagempor JoséQuintas » 14 Ago 2020 11:04

Uma coisa interessante no SQL, é que acabamos usando campo incremental e tudo de preferência numérico.
Mas mesmo em DBF, isso seria muito bom.

Aqui eu usava código de cliente caractere com 6 posições.
Tudo normal, 6 posições dá um limite de quase 1 milhão de códigos, é suficiente.
E usei isso pra tudo, 1 milhão de limite.... ótimo.
TODAS as rotinas direcionadas a esse código de 6 dígitos.
Tudo bem.... até precisar de mais um dígito.

Já como numérico... o máximo que precisaria fazer seria aumentar um dígito nas bases de dados, à primeira vista sem mexer em nenhum outro fonte.

E no SQL... o código incremental.... é um campo numerado automaticamente.
Vamos comparar com o RecNo().
Imagine que o RecNo() não se alterasse num PACK, que ele fosse eterno.
Ao incluir registros, não importa quantas estações fizessem inclusão, o RecNo() seria único.
Seria o fim de chave duplicada, e coisas do tipo. É assim o campo incremental no SQL (DBF também tem isso).
Não precisa inventar código, a base de dados já numera, com número único pra cada registro.

Em DBF o que mais precisaria? Talvez um índice em Str( numero, 10 )
Não importa se o número usa menos dígitos, o índice de 10 dígitos atende do mesmo jeito.
E isso deixa preparado pra qualquer limite, até 10 dígitos, esse é o ponto.
Se usa 5 dígitos, mas depois precisa de 6... tá pronto, não precisa mexer em nada.
Em bases monstruosas, um dígito pode fazer diferença pra economizar espaço, mas.... deixar preparado pra algo ilimitado parece ser muito mais interessante.

Olhar como o SQL trabalha, parece ser interessante até pra facilitar no DBF.

Você precisa de um relatório do total de vendas por cliente, e por produto, em ordem alfabética de cliente e de produto.
O mais comum é pensar em aproveitar os índices:

SELECT movimento
INDEX ON codigocliente + codigoproduto + data TO TEMP1
SELECT produtos
INDEX ON nomeproduto TO temp2
SELECT clientes
INDEX ON nomecliente to temp3
GOTO TOP
DO WHILE ! Eof()
   nCodigoCliente := clientes->Codigo
   SELECT produtos
   GOTO TOP
   DO WHILE ! Eof()
      nCodigoProduto := produtos->Codigo
      SELECT movimento
      SEEK Str( nCodigoCliente, 6 ) + Str( nCodigoProduto, 6 ) SOFTSEEK
      nTotal := 0
      DO WHILE nCodigoCliente == movimento->CodigoCliente .AND. nCodigoProduto == movimento->CodigoProduto .AND. ! Eof()
         nTotal += movimento->Valor
         SKIP
      ENDDO
      IF nTotal != 0
         ? clientes->Nome, produtos->Nome, nTotal
      ENDIF
      SELECT produto
      SKIP
   ENDDO
   SELECT cliente
   SKIP
ENDDO


Ok, podemos aproveitar índice existente mas...
O problema do DBF NÃO é criar índice, é extrair informações quando a base é grande.

Como o SQL faria?
Esse é o ponto.
O objetivo do índice é facilitar pesquisar informações, não é deixar índice pronto pra relatório.
Um índice pra relatório pode deixar mais lento, e não mais rápido.

Como acima ficaria mais rápido? extraindo informações com o índice que já existe.

SELECT clientes
INDEX ON CodCliente to temp1
SELECT produtos
INDEX ON CodProduto TO temp2
SELECT movimento
INDEX ON Str( CodigoCliente, 6 ) + Str( CodigoProduto, 6 )
GOTO TOP
DO WHILE ! Eof()
   nCodigoCliente := movimento->CodigoCliente
   Encontra( cCodigoCliente, "clientes" )
   DO WHILE nCodigoCliente == movimento->CodigoCliente .AND. ! Eof()
      nCodigoProduto := movimento->CodigoProduto
      Encontra( nCodigoProduto, "produtos" )
      nTotal := 0
      DO WHILE nCodigoCliente == movimento->CodigoCliente .AND. nCodigoProduto == movimento->CodigoProduto .AND. ! Eof()
         nTotal += movimento->Valor
         SKIP
      ENDDO
      SELECT temp
      APPEND BLANK
      REPLACE temp->CodigoCliente WITH nCodigoCliente, temp->CodigoProduto WITH nCodigoProduto, temp->Total WITH nTotal, ;
      temp->NomeCliente WITH clientes->Nome, temp->NomeProduto WITH produtos->Nome
      SELECT movimento
   ENDDO
ENDDO
SELEC temp
INDEX ON NomeCliente + NomeProduto TO temp4
GOTO TOP
LIST NomeCliente, NomeProduto, Total


Qual a diferença?
A segunda forma trabalha com o que interessa totalizar, faz a totalização de forma rápida.
O índice fica para o final, porque só interessa pra mostrar o resultado.
Se fosse por data, um índice por data deixaria mais rápido ainda.

Essa é uma confusão comum em DBF e também em SQL.
O índice NÃO é pra facilitar mostrar organizado, o índice é pra fazer cálculos mais rápido, pra extrair informações mais rápido.
Supondo que a movimentação seja por data, e queira apenas um dia, com certeza o índice por data vai deixar muito mais rápido do que um índice em ordem alfabética.

No DBF, o fonte é que deve escolher o melhor índice pra extrair informação rápido.
No SQL, a base de dados é quem escolhe automaticamente, mas... se não existir um índice bom, vai qualquer um.

O segundo caso acima é interessante porque se aproxima do SQL.
O comando que vai ao SQL, seria o equivalente desssa rotina, e o retorno é o resultado obtido no temporário dessa rotina.

Porque o SQL é rápido:
Porque ele escolhe o melhor índice, ele faz o processo no servidor, e pro terminal só vém esse temporário.
E como o servidor só é servidor.... ele aproveita pra deixar em memória tudo que é muito acessado, pra tudo ficar mais rápido ainda.
Compare com o CACHE de disco... o Windows não tem o cache de disco? então... o SQL tem algo parecido, só pras bases de dados.
E temporários em memória, pra ficar rápido, etc. etc. etc. etc.

O SQL foi apenas uma "linguagem padrão" que definiram, pra facilitar para os programadores, pra não ficar aprendendo um monte de coisa diferente.
Ao mesmo tempo... isso permitiu que as bases de dados pudessem fazer agilizações direcionadas aos comandos, já que os comandos mostravam as necessidades.

Conclusão:
Tudo que alguém poderia fazer pra deixar alguma coisa mais rápida, é o que um gerenciador de banco de dados já faz.
Com todo mundo usando SQL pra "criar temporários", toda agilização pra isso está lá pronta pra uso.
Lógico, em tudo existe exceção.... mas exceção é algo que acontece só em determinada situação. Quando isso acontecer, faremos diferente e pronto.

Nota:
Dá pra deixar o DBF tão rápido quanto SQL?
Impossível, porque, por mais que a gente agilize, ainda vai ser trabalhar pela rede, coisa que cada vez fica mais lenta e com mais interferências...
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 14712
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 869 vezes



Retornar para Contribuições, Dicas e Tutoriais

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 2 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro