none
Asp.Net MVC Muitos Clientes & Restriçãod e Registros RRS feed

  • Pergunta

  • Olá ..

    Estou fazendo uma pesquisa, para que eu possa ter embasamento técnico, para propor um caminho de desenvolvimento de um aplicativo aqui na empresa.

    Trata-se de um aplicativo, que atenderá certa demanda de vários cliente, como por exemplo controle financeiro e estoque.

    A questão é qual a melhor forma para abordar as seguintes questões :

    1 - Cada cliente terá seu próprio banco de dados ? ou Terá banco de dados compartilhado ?

    O que vocês acham disso ? Quais as suas experiências com isso ? é melhor ter separado, é melhor não ter separado. Vamos imaginar nas atualizações... no tamanho do banco.

    2 - Se for db compartilhado (único db) como ficará as listagens (index) para uma tabela de Nota por exemplo ?

    Vamos imaginar que cada cliente nosso tem um ID, e nos registros dentro do banco esta ID está na coluna

    Então na tabela NOTA tera assim:

    Select * from Nota
    
    ID,  Nota,   Data,   Valor .....
    1,   123     01/01   1200.00
    1,   124     01/01   1200.00
    2,   12      01/01   100.00
    2,   13      01/01   120.00
    2,   14      01/01   130.00

    Quando o cliente com a ID no usuario for 1, ele poderá ver somente as notas com a ID 1 certo ?

    e qual a melhor forma de tratar isso no Index ? Fizemos testes assim: string ID = 1 << vindo do usuario logado

    Index:

    var data = Db.Nota.Where(a => ID.Contains(a.ID)).ToList();

    Mas é o melhor método ? e a performance disso ? existe outro método melhor ? e a manutenção disso depois ? Da para usar algo no Filter nao dá ?

    É isos, não são questão muito técnicas, preciso da opinião de vocês, como vcs abordariam imaginando que estivessem na mesma situação...

    Att,


    Isco Sistemas José Luiz Borges

    segunda-feira, 13 de julho de 2015 11:44

Respostas

  • Eu pensaria no volume de dados por cliente, se cada cliente possuir um volume gigantesco (na faixa de trilhões) de notas talvez seja interessante manter em bancos diferentes. Porém nada impede de você manter isso em um único banco, você só terá um pouco mais de desenvolvimento para manter a integridade por cliente. Sobre a performance de tudo em único banco, se os indices estiverem certinhos acredito que não terá problemas.

    Se o software for SAAS, pode ser mais interessante manter tudo em único banco pois senão terá que desenvolver um chaveador de conexão, por exemplo:

    caso cliente1 => banco1

    caso cliente2 => banco2

    Não que isso seja difícil porém é mais desenvolvimento... 

    Quando você comenta sobre "var data = Db.Nota.Where(a => ID.Contains(a.ID)).ToList();é sobre entity framework? Se for avaliar o Entity Framework puramente, ele certamente será muito mais lento que realizar a consulta puramente. Mas temos que levar em conta que ele faz o bind automático em nossos objetos. Além do ganho em velocidade de desenvovimento.


    Att. Andre de Mattos Ferraz - www.iamferraz.com.br - http://mbsy.co/ldecrespigny/19022985

    • Marcado como Resposta Jose Luiz Borges segunda-feira, 13 de julho de 2015 19:02
    segunda-feira, 13 de julho de 2015 12:09
  • Opa obrigado por responder....

    Ok.. o volume por registro é pequeno , mas ira aumentar (já que nunca apagaríamos NF da base).

    Concordo com você na questão dos índices do banco.

    O  Software é SAAS e gostaríamos muito de manter 1 banco, quanto ao chaveador é bem tranquilo até ja tenho, a questão é 1 ou N banco mesmo..


    Agente espera usar o Entity Framework 100%, até pela agilidade do desenvolvimento. Você pensaria em não usar o EF ? Mas ele faz o bind né.. é muito rápido desenvolver com ele...

    Na questão lia do INDEX, como vc faria ?

    Opção1:

    Var data = (from a db.Nota where VARIAVEL_ID.Contains(a.ID)).tolist();

    Não da para usar "where a.id == VARIAVEL_ID" pois existe usuários que terão acesso a + de 1 id):

    Você pensa em mais alguma possibilidade aqui ?

    Acha que usando FILTER é possível ?

    O Cenário exatamente é esse.

    Tabela Nota:  ID, COD_EMPRESA, COD_REGIONAL,NUM_NOTA,......

    ID = Terá que ser filtrado pelo usuário ativo

    COD_REGIONAL, COD_EMPRESA = Terá que ser filtrado pelo usuário ativo (Matriz / Filial), mas aqui ele pode mudar/alternar entre elas se ele tiver acesso.

    Então como vc escreveria o método INDEX por exemplo ?

    Obrigado








    Isco Sistemas José Luiz Borges

    • Marcado como Resposta Jose Luiz Borges segunda-feira, 13 de julho de 2015 19:02
    segunda-feira, 13 de julho de 2015 15:40

Todas as Respostas

  • Eu pensaria no volume de dados por cliente, se cada cliente possuir um volume gigantesco (na faixa de trilhões) de notas talvez seja interessante manter em bancos diferentes. Porém nada impede de você manter isso em um único banco, você só terá um pouco mais de desenvolvimento para manter a integridade por cliente. Sobre a performance de tudo em único banco, se os indices estiverem certinhos acredito que não terá problemas.

    Se o software for SAAS, pode ser mais interessante manter tudo em único banco pois senão terá que desenvolver um chaveador de conexão, por exemplo:

    caso cliente1 => banco1

    caso cliente2 => banco2

    Não que isso seja difícil porém é mais desenvolvimento... 

    Quando você comenta sobre "var data = Db.Nota.Where(a => ID.Contains(a.ID)).ToList();é sobre entity framework? Se for avaliar o Entity Framework puramente, ele certamente será muito mais lento que realizar a consulta puramente. Mas temos que levar em conta que ele faz o bind automático em nossos objetos. Além do ganho em velocidade de desenvovimento.


    Att. Andre de Mattos Ferraz - www.iamferraz.com.br - http://mbsy.co/ldecrespigny/19022985

    • Marcado como Resposta Jose Luiz Borges segunda-feira, 13 de julho de 2015 19:02
    segunda-feira, 13 de julho de 2015 12:09
  • Opa obrigado por responder....

    Ok.. o volume por registro é pequeno , mas ira aumentar (já que nunca apagaríamos NF da base).

    Concordo com você na questão dos índices do banco.

    O  Software é SAAS e gostaríamos muito de manter 1 banco, quanto ao chaveador é bem tranquilo até ja tenho, a questão é 1 ou N banco mesmo..


    Agente espera usar o Entity Framework 100%, até pela agilidade do desenvolvimento. Você pensaria em não usar o EF ? Mas ele faz o bind né.. é muito rápido desenvolver com ele...

    Na questão lia do INDEX, como vc faria ?

    Opção1:

    Var data = (from a db.Nota where VARIAVEL_ID.Contains(a.ID)).tolist();

    Não da para usar "where a.id == VARIAVEL_ID" pois existe usuários que terão acesso a + de 1 id):

    Você pensa em mais alguma possibilidade aqui ?

    Acha que usando FILTER é possível ?

    O Cenário exatamente é esse.

    Tabela Nota:  ID, COD_EMPRESA, COD_REGIONAL,NUM_NOTA,......

    ID = Terá que ser filtrado pelo usuário ativo

    COD_REGIONAL, COD_EMPRESA = Terá que ser filtrado pelo usuário ativo (Matriz / Filial), mas aqui ele pode mudar/alternar entre elas se ele tiver acesso.

    Então como vc escreveria o método INDEX por exemplo ?

    Obrigado








    Isco Sistemas José Luiz Borges

    • Marcado como Resposta Jose Luiz Borges segunda-feira, 13 de julho de 2015 19:02
    segunda-feira, 13 de julho de 2015 15:40
  • Eu também usaria o EF, ainda mais se a base for SQLSever... 

    Sobre a questão de permissão/acesso, eu criaria uma ou mais tabelas para fazer esse controle. Por exemplo, NotasUsuarios, UsuariosRegional...


    Att. Andre de Mattos Ferraz - www.iamferraz.com.br - http://mbsy.co/ldecrespigny/19022985

    segunda-feira, 13 de julho de 2015 16:22
  • Certo.. A Base é Sql Server mesmo...


    Sobre a questão de permissão/acesso: Você quer adicionar para que a instrução sql enviada seja algo com

    Select a.* from Nota a Inner join NotasUsuario b on a.... = b..... Where b.id= @id

    e não assim

    Select a.* from Nota a Where id.in (@id)

    Certo ?

    Mas acho que UsuarioNota vai engessar um pouco, pois o acesso são as Notas de um determinado ID, assim parece estar vinculado sempre ao usuário, mas eu entendi o objetivo... Tipo ter uma tabela de controle de usuario x id e relacionar esta tabela com a nota.


    Exemplo:

    Tabela Nota

    ID, COD_EMPRESA, NUM_NOTA....

    Tabela Usuário

    COD_USUARIO, NOME, ID...

    Tabela USUARIOXID

    COD_USUARIO, ID

    No EF do Index por Exemplo ficaria asism:

    Var data = 
    (from a in db.Nota 
    inner join b in Usuarioxid on a.id = b.id
    inner join c in Usuario on c.id = a.id
    where c.cod_usuario = @cod_usuario ).ToList();

    *** estou sem o VS não tenho certeza se a sintax esta correta ... ***

    é isso né?

    realmente ficara melhor que usar o "Contain" que vai gerar um "IN" como instrução sql..


    Se tivesse como colocar isso no filter né.. tipo no Controller vai estar herdado de um controller mestre.

    e sempre seria assim var data = db.Nota.Tolist();

    e no controller mestre ele identificar e adicionar o "where".. mas o controller mestre vai ser herdado  varias vezes por outras tabelas..


    Mas é isso né que vc pensa..






    Isco Sistemas José Luiz Borges

    segunda-feira, 13 de julho de 2015 16:46
  • Foi dessa forma que pensei.

    Att. Andre de Mattos Ferraz - www.iamferraz.com.br - http://mbsy.co/ldecrespigny/19022985

    segunda-feira, 13 de julho de 2015 18:55
  • Cara valew...

    Vou elaborar um doc. para apresentar como estratégia de desenvolvimento assim:

    1 - Usando 1 Banco de dados para clientes com fat. pequeno.

    share.sistema.dominio.com.br exemplo...

    2 - Usar uma chave seletora já desde o inicio para contemplar clientes exigente e que não queriam compartilhar o d.

    cliente.sistema.dominio.com.br exemplo

    3 - Usar tabela de ligação para validar se o usuário tem acesso ao ID ou não (para não usar Contains)

    Valew cara..



    Isco Sistemas José Luiz Borges

    segunda-feira, 13 de julho de 2015 19:02
  • Tranquilo, boa sorte no desenvolvimento.

    Att. Andre de Mattos Ferraz - www.iamferraz.com.br - http://mbsy.co/ldecrespigny/19022985

    segunda-feira, 13 de julho de 2015 20:06