sexta-feira, 5 de setembro de 2014

Porque é que os drives amovíveis ainda usam FAT32?

Prosseguindo nesta temática dos Sistemas de Ficheiros, apresentamos mais um pequeno artigo que ajuda a esclarecer uma questão prática importante.

O Microsoft Windows XP começou a usar o sistema de ficheiros NTFS como padrão para as suas unidades internas por volta de 2001. Mais de 12 anos depois, por que é que as Pen Drives USB, cartões SD e outros drives removíveis continuam a usar o FAT32?

Isto não é um erro dos fabricantes. Estas unidades podem ser formatadas num sistema de ficheiros diferente, como o NTFS, mas, provavelmente, vai querer mantê-las formatadas em FAT32.

Porque é que a Microsoft inventou o NTFS? 

A Microsoft criou o NTFS para melhorar o FAT32. Para percebermos porque o Windows utiliza o NTFS, vamos analisar alguns dos problemas do FAT32 e como o NTFS os resolveu:

  • O FAT32 apenas suporta ficheiros individuais até 4GB de tamanho e volumes até 2TB. P. ex., se tiver um ficheiro de vídeo maior que 4GB, não consegue gravá-lo em FAT32, assim como não consegue formatar um disco de 3TB como uma unidade única. O NTFS tem limites muito mais elevados.
  • O FAT32 não é um sistema de ficheiros que suporte journaling, o que significa que a corrupção de ficheiros pode acontecer com muito mais facilidade. Com o NTFS, as alterações são registadas num "diário" na unidade antes de serem realmente feitas. Se o computador for abaixo a meio duma operação de escrita dum ficheiro, o sistema não vai precisar de uma longa e exaustiva operação de scan do disco, para recuperar.
  • O FAT32 não suporta permissões de ficheiro. Com o NTFS, as permissões de ficheiro permitem maior segurança. Os ficheiros de sistema podem ser marcados como somente de leitura e os programas normais tão lhes podem mexer, os utilizadores podem ser impedidos de ver os ficheiros de outros utilizadores, e assim por diante.

Pelo acima exposto, existem muito boas razões para que o Windows utilize o NTFS nas partições de sistema. O NTFS é mais seguro, robusto e suporta ficheiros e drives maiores.

Mas estes não são problemas em unidades amovíveis

É claro que nenhuma das questões anteriores é realmente um problema em pens USB e cartões SD. Eis o porquê:

  • Para já, as pen drives USB ou cartões SD estão definitivamente abaixo de 2TB, pelo que não há problemas com o limite do tamanho do drive. Ocasionalmente pode ser necessário guardar um ficheiro maior que 4 GB. Esta é a única situação em que pode querer formatar o disco como NTFS.
  • Uma unidade amovível não necessita dum registo em diário como uma unidade de sistema. Na verdade, o journaling resulta em gravações adicionais que podem reduzir a vida útil da memória flash da unidade.
  • Um dispositivo amovível também não necessita de permissões de ficheiro. Na verdade, estas podem causar problemas quando se ligam os dispositivos amovíveis em máquinas diferentes. P.ex., os ficheiros podem ser marcados como acessíveis apenas por determinado ID de utilizador. Isto funciona bem se a unidade ficar dentro do mesmo computador. No entanto, se era uma unidade amovível, qualquer pessoa com o mesmo ID de utilizador pode aceder aos ficheiros, no outro computador. Neste caso, as permissões de ficheiro não aumentam realmente a segurança, apenas acrescentam uma complexidade adicional.

Não há realmente nenhuma razão para usar o NTFS em pen drives USB e cartões SD, a menos que seja realmente necessário suporte para ficheiros com mais de 4GB de tamanho. Nesse caso, terá que converter ou reformatar a unidade para NTFS.

Claro que hoje já se podem adquirir discos rígidos externos, com ligação USB, com mais de 2 TB de espaço de armazenamento e também é mais provável guardar ficheiros com mais de 4GB num discos destes. É natural que venham formatados em NTFS, para que possam usar o tamanho total do armazenamento em uma única partição. A menos que sejam construídos com tecnologia de memória flash (ainda muito caro), não há problema das operações de escrita adicionais do journaling.

Compatibilidade

A compatibilidade é provavelmente a principal razão para querer usar o sistema de ficheiros FAT32 nas unidades flash USB ou cartões SD. Enquanto as versões modernas do Windows suportam o NTFS, outros dispositivos podem não o conseguir da mesma forma:

  • O Mac OS X tem suporte nativo de leitura para unidades NTFS, mas necessita de drivers e ajustes adicionais para conseguir escrever.
  • O Linux já possui um suporte sólido de leitura/escrita em NTFS, mas durante muitos anos não foi assim.
  • Leitores DVD, Smart TVs, impressoras, câmaras digitais, leitores de média, Smartphones, qualquer coisa com uma porta USB ou slot de cartão SD: Aqui é que realmente começa a ficar complicado. Muitos dispositivos têm portas USB ou slots para cartões SD. Todos estes dispositivo estão projectados para trabalhar com FAT32, para que eles possam "funcionar simplesmente" e ser capazes de ler os seus ficheiros, desde que use FAT32. Alguns dispositivos até funcionarão com o NTFS, mas não pode contar com isso para todos. Na verdade, deve supor que a maioria dos dispositivos só pode ler FAT32 e não NTFS

É principalmente por isto que vai querer usar FAT32 nos seus discos amovíveis. Desta forma pode usá-los em praticamente qualquer dispositivo. Não há muito a ganhar com a utilização do NTFS numa pen drive USB, para além do suporte para ficheiros de mais de 4GB de tamanho.

Referências

http://www.howtogeek.com/177529/htg-explains-why-are-removable-drives-still-using-fat32-instead-of-ntfs/

Sistemas de Ficheiros: o que são e porque há tantos?

Introdução

Sistemas Operativos (SO) diferentes suportam Sistemas de Ficheiros diferentes. O disco que usa no MAC não funciona num PC Windows e o Linux tem os seus próprios sistemas de ficheiros também.

Neste artigo vamos falar um pouco sobre Sistemas de Ficheiros, o que são e porque há tantos diferentes.

Um comum utilizador de computadores não precisa saber a maioria destes detalhes - que deveriam ser transparentes e simples - mas conhecer o básico ajuda a compreender questões como: "Por que razão este disco formatado no Mac não funciona no meu PC Windows?" e "Devo formatar este drive USB como FAT32 ou NTFS?"

Conteúdo

O que são Sistemas de Ficheiros

O Sistema de Ficheiros é a forma de organização da informação num dado dispositivo de armazenamento de dados.

Sistemas de Ficheiros diferentes são simplesmente diferentes formas de organizar e armazenar ficheiros no disco rígido, unidade flash, ou qualquer outro dispositivo de armazenamento. Cada dispositivo tem uma ou mais partições de armazenamento e cada partição é formatada com um dado sistema de ficheiros.

Um sistema de ficheiros fornece uma forma de separar os dados na unidade de armazenamento em partes individuais, que são os ficheiros. Adicionalmente, fornece uma maneira de armazenar informação sobre estes ficheiros – p.ex., os seus nomes, permissões e outros atributos.

O sistema de ficheiros também fornece um índice - uma lista dos ficheiros na unidade e onde estão localizados – para o SO poder ver o que está na unidade num único lugar, em vez de ter que pesquisar todo o disco para encontrar um ficheiro.

O SO tem que conhecer o sistema de ficheiros do dispositivo, de forma a poder mostrar o seu conteúdo e abrir ou gravar ficheiros. Se o SO não entender o sistema de ficheiros de um dado dispositivo, é necessário instalar um driver que forneça suporte ao mesmo - ou simplesmente não vai ser possível usar o sistema de ficheiros com aquele SO específico.

Porque existem tantos Sistemas de ficheiros? 

Nem todos os sistemas de ficheiros são iguais. Sistemas de ficheiros diferentes têm diferentes formas de organizar os seus dados. Alguns sistemas de ficheiros são mais rápidos que outros, alguns têm características de segurança adicionais, outros oferecem suporte a unidades com maior capacidade de armazenamento. Alguns sistemas de ficheiros são mais robustos e resistentes à corrupção de ficheiros, enquanto outros trocam essa robustez por velocidade adicional.

Não existe um sistema de ficheiros que seja o melhor para todos os casos.

Cada SO tende a usar o seu próprio sistema de ficheiros, no qual trabalham os programadores do SO. Há muito trabalho envolvido na concepção de um sistema de ficheiros e isso pode ser feito de muitas maneiras diferentes. Um sistema de ficheiros não é como uma partição, que é simplesmente um pedaço de espaço de armazenamento. Um sistema de ficheiros especifica como os ficheiros são gravados, organizados, indexados, e como os metadados são associados a eles.

Troca de Sistema de Ficheiros 

Cada partição é formatada com um dado sistema de ficheiros. Às vezes, é possível "converter" uma partição para um sistema de ficheiros diferente e manter os mesmos dados, mas raramente é uma opção fácil. Provavelmente, é preferível copiar os dados importantes para outra partição ou outro dispositivo, primeiro, como segurança.

Atribuir um novo sistema de ficheiros à partição, consiste simplesmente em formatá-la com esse sistema de ficheiros, no SO que o suporta. Por exemplo, uma unidade formatada para Linux ou Mac, pode ser formatada com o NTFS ou FAT32, para obter uma unidade para usar no Windows.

As partições também são automaticamente formatadas com o sistema de ficheiros adequado durante o processo de instalação do SO. P.ex., se quisermos instalar o Linux numa partição previamente formatada no Windows, o processo de instalação do Linux vai formatar essa partição NTFS ou FAT32 para o sistema de ficheiros Linux preferido pela distribuição escolhida.

Em conclusão, se quisermos alterar o sistema de ficheiros de um dispositivo de armazenamento, devemos começar por fazer um backup dos dados (para outro disco ou partição) e de seguida formatar essa unidade ou partição com uma uma ferramenta do tipo Gestão de Discos, no Windows, GParted no Linux ou Disk Utility no Mac.

 

Sistema de Ficheiros mais comuns 

Um pequeno resumo dos Sistemas de Ficheiros mais comuns no mercado.

Sistema de Ficheiros
Sistema Operativo
Descrição
MS-DOS
Windows
O FAT32 é um sistema de ficheiros antigo do Windows, mas ainda é usado em dispositivos de removíveis - apenas nos de menor capacidade, no entanto. Discos rígidos externos com 1 TB ou mais, provavelmente, são formatados de raíz com NTFS. O FAT32 só é usado em dispositivos pequenas ou para compatibilidade com outros equipamentos, como câmaras digitais ou consolas de jogos, que não suportam o sistema de ficheiros NTFS, mais recente
Windows
As versões mais modernas do Windows (a partir do Windows NT) passaram a usar o NTFS para a sua partição de sistema. As outras partições e discos externos podem ser formatadas em NTFS ou FAT32
Mac
Os SO da Apple usam HFS+ para as suas partições internas, bem como em discos externos – obrigatório se quisermos usar um drive externo com Time Machine. O Mac também pode ler e gravar em FAT32 nativamente e em NTFS após instalar o driver adequado
Linux
Estes são os sistemas de ficheiros mais usados no Linux. O Ext2 é um sistema de ficheiros antigo, que carece de recursos importantes como journaling. O Ext3 acrescenta estas características de robustez à custa de um pouco de velocidade. O Ext4 é mais moderno e mais rápido - é o sistema de ficheiros padrão na maioria das distribuições Linux de hoje em dia. O Windows e Mac não suportam estes sistemas de ficheiros – é necessária uma ferramenta de terceiros para aceder a ficheiros em ExtX.
Por esta razão, muitas vezes o ideal é formatar as partições do sistema Linux como Ext4 e deixar os dispositivos removíveis formatados com FAT32 ou NTFS, se for necessária compatibilidade com outros SO. O Linux pode ler e gravar em FAT32 ou NTFS
Linux
“B-Tree FS” ou “Better FS” é um novo sistema de ficheiros Linux, que ainda está em desenvolvimento. Ainda não é o padrão na maioria das distribuições Linux, mas pretende-se que venha a substituir o Ext4. O objetivo é fornecer recursos adicionais que permitam ao Linux escalar para uma maior quantidade de armazenamento

Nota: esta lista não é exaustiva. Há muitas mais opções diferentes, principalmente no reino do Linux e Unix.

Referências

http://pt.wikipedia.org/wiki/Sistema_de_ficheiros
http://en.wikipedia.org/wiki/Comparison_of_file_systems
http://en.wikipedia.org/wiki/List_of_file_systems

http://windows.microsoft.com/pt-pt/windows-vista/comparing-ntfs-and-fat-file-systems

http://www.howtogeek.com/196051/htg-explains-what-is-a-file-system-and-why-are-there-so-many-of-them/

sexta-feira, 29 de agosto de 2014

Escolher um sistema de RAID

Introdução

Quando se pensa em adquirir ou configurar um Servidor, uma das primeiras preocupações é escolher o sistema de RAID mais adequado.

Neste artigo não se pretende descrever exaustivamente as várias arquitecturas e níveis de RAID, mas sim apresentar uma comparação entre as opções mais utilizadas e tentar perceber qual a melhor opção para cada caso.

Vamos apenas referir que um sistema RAID é composto por um conjunto de 2 ou mais unidades de disco iguais, com dois objectivos base:

  • Maior rapidez de leitura e escrita (I/O) dos dados (striping)
  • Maior segurança dos dados e tolerância a falhas (mirror)

Para quem queira perceber melhor o que é o RAID e as várias opções disponíveis, a Wikipédia oferece uma explicação muito clara e concisa, aqui.

Conteúdo

Níveis de RAID e utilização de discos

Embora não seja o objectivo deste artigo a descrição detalhada das tecnologias de RAID, é útil apresentar uma tabela com a utilização de discos para cada nível.

Nível
Designação
Redundância
Utilização Discos p/ Dados
Nº Mínimo Discos
0
Striping
Não
100%
2 (n*2)
1
Mirror
Sim
50%
2 (n*2)
5
Paridade
Sim
66.6% – 97%
3 (n+1)
6
Paridade (recente)
Sim
50% – 88%
4 (n+2)
01 / 10
Striping + Mirror
Sim
50%
4 (n*2*2)
50
Paridade + Striping
Sim
66.6% – 97%
2 (n*2)
100
Striping + Mirror + Striping
Sim
50%
8 (n*2*2*2)

Nota: não são apresentados os níveis RAID 2, 3 e 4, porque caíram em desuso

Níveis de RAID base

RAID 0

Divide-se a gravação dos dados por dois ou mais discos, em simultâneo, aumentando assim a velocidade de I/O. Num sistema de dois discos, p.ex., o tempo que leva a gravar 1 byte num só disco, permite a gravação simultânea de 2 bytes (um em cada disco). Quantos mais discos tiver o sistema de RAID, mais rápida será a velocidade.

Toda a capacidade dos discos é aproveitada para os dados, todavia, se um dos discos falhar, todo o sistema falha, com perda total dos dados.

RAID 1

Cada disco, onde os dados são gravados, tem outro igual que funciona como espelho (mirror). Neste nível de RAID, os discos são sempre instalados aos pares.

Apesar de cada par ter discos iguais, somente a capacidade de um deles é aproveitada para guardar os dados. Todavia, se um dos discos falhar, o outro entra imediatamente em funcionamento, não havendo falhas no sistema.

RAID 5

Neste nível o foco também está na redundância e recuperação dos dados, mas em vez de existir um disco completo como réplica, a própria unidade garante a protecção dos dados. Isto permite uma poupança de recursos em relação ao RAID 1, podendo, inclusivamente, configurar-se RAID 5 num número ímpar de discos.

A redundância é obtida recorrendo a algoritmos de paridade. Os dados gravados no disco são divididos em pequenos blocos e cada um deles recebe um bit adicional – o bit de paridade, de acordo com a seguinte regra: se a quantidade de bits '1' do bloco for par, seu bit de paridade é '0'; se a quantidade de bits '1' for ímpar, o bit de paridade é '1'.

Estes bits de paridade são gravados numa área específica do próprio disco cujo tamanho é proporcional à quantidade de blocos de dados a controlar. Quando há uma falha (bit desconhecido), basta contar a quantidade de bits ‘1’ do bloco + bit paridade. Se for par, o bit em falta é ‘0’, se for ímpar, o bit em falta é ‘1’.

Tipicamente, numa configuração multidiscos, o espaço reservado para a paridade corresponde ao tamanho de um disco individual. Assim, numa configuração de 3 discos de 500 GB, ficamos com 1 TB para dados e 500 GB para paridade (33.33%).

RAID 0+1 vs RAID 1+0

A combinação dos níveis RAID 0 e RAID 1, permite obter o melhor de dois mundos:

  • O mirror dá-nos o mais alto nível de disponibilidade e os mais rápidos tempos de reconstrução, quando um disco falha;
  • O striping é a base da alta performance de I/O.

A combinação destes dois níveis, pode ser feita de duas formas:

  • RAID 01: primeiro fazemos o stripe e depois o mirror;
  • RAID 10: primeiro fazemos o mirror e depois o stripe.

À primeira vista parece que os processos são semelhantes e comutativos, mas não são. Vamos perceber porquê (exemplos para 3+3 discos):

RAID 0+1 ou RAID 01

Primeiro faz-se o stripe dos discos:

E depois faz-se o mirror do conjunto de discos em stripe:

 

RAID 1+0 ou RAID 10 

Primeiro faz-se o mirror de cada um dos discos:

E depois faz-se o stripe pelos pares de discos em mirror:

 

Diferenças

OK, a arquitectura interna pode ser um pouco diferente, mas o resultado final é o mesmo: usamos o mesmo número de discos, temos o mesmo disco lógico, fazemos striping por 3 discos (velocidade a triplicar) e temos redundância de dados. Porque é que nos temos que preocupar?

Temos que nos preocupar porque a grande diferença está na tolerância a falhas.

Relembremos que o RAID 1 tem uma tolerância de 1 disco por cada par em mirror.

Na configuração em RAID 01, temos apenas um mirror (de um stripe de 3 discos), pelo que o sistema apenas permite falha num dos discos físicos. Se um disco falhar, o sistema, automaticamente, começa a usar o outro bloco do mirror. Se falhar um segundo disco, desse bloco, o sistema pára.

No caso do RAID 10, temos 3 mirrors, pelo que o sistema permite a falha de um disco em cada par. Por exemplo, podem falhar os discos 1, b e 3 e o sistema continuar a funcionar. Claro que se falharem dois discos do mesmo par em mirror (p.ex. 1 e a) o sistema pára também.

A conclusão é que temos mais vantagem em usar o RAID 10 em vez do RAID 01 porque, com o mesmo número de discos, obtemos a mesma performance mas uma melhor tolerância a falhas.

RAID 10 vs RAID 50

RAID 50

De forma análoga ao RAID 10, numa configuração de RAID 50, primeiro faz-se RAID 5 e de seguida faz-se stripe aos discos já com redundância.

Diferenças

Performance
Uma configuração RAID 50 permite leituras mais rápidas que numa RAID 10, com o mesmo número de discos. No entanto, as operações de escrita em RAID 50 são mais lentas do que em RAID 10. Esta diferença torna-se muito significativa em operações de escrita intensiva (p.ex. bases de dados).

A correcção de performance de um sistema em RAID 50 é cara, exigindo ou a compra de muito mais discos RAID 5 do que aqueles inicialmente previstos, ou a conversão num sistema RAID 10, que tem um menor custo por operação de escrita.

Uma configuração RAID 50, apesar de ser tolerante à falha de uma disco, sofre uma degradação massiva de performance quando isto ocorre. Numa configuração RAID 10, se um disco falhar, o sistema continua a funcionar sem qualquer degradação de performance.

Redundância
Uma configuração RAID 10 oferece mais redundância de dados que uma RAID 50. 

Arquitectura
Uma configuração RAID 10 oferece maior flexibilidade de arquitectura do que uma RAID 50. Para além disso, a quantidade de espaço livre também é minimizada ao usar uma configuração RAID 10.

Controlador
Uma configuração RAID 5 exige uma placa controladora de alto desempenho. Se a implementação de RAID 5 estiver a ser feita pelo sistema operativo,  então o resultado será o de abrandar o desempenho do computador. No caso de uma configuração RAID 10, qualquer controlador de hardware pode ser utilizado.

Ocorrência falhas
Uma configuração RAID 50 tem uma probabilidade de falha, pelo menos, 3 vezes superior a uma configuração RAID 10 equivalente. E quanto maior for o número de discos RAID 5, mais aumenta esta probabilidade.

Recuperação de dados
A recuperação de dados numa configuração RAID 5 vai consumir cerca de metade da capacidade de IOPS (Operações de I/O por segundo) e ainda alguns ciclos do controlador ou do CPU. A recuperação de dados numa configuração RAID 10 é tão simples como copiar um disco.

Custos
A principal motivação para o aparecimento do RAID 5 foi o elevado custo por byte dos discos, para fazer RAID 1. Mas isso foi conseguido à custa do sacrifício da performance. Hoje em dia o custo dos discos já não é tão significativo e a exigência de um controlador mais sofisticado provoca que os sistemas em RAID 50 não ofereçam vantagens económicas significativas em relação ao RAID 10.

Conclusões

Pelo que foi exposto, na grande maioria dos cenários, uma configuração RAID 10 é a que apresenta mais vantagens.

O RAID 01 não oferece qualquer vantagem sobre o RAID 10 e o RAID 50 tem graves problemas de performance nas operações de escrita. Este último poderá ser equacionado quando há um pequeno número de discos (até 3) ou em sistemas em que o peso está nas operações de leitura.

Em qualquer dos casos, deve-se fazer sempre uma análise cuidadosa do cenário, requisitos e recursos disponíveis para implementar uma solução de RAID.

Referências

http://www.zdnet.com/blog/storage/raid-10-is-the-cadillac-of-raid/131

http://www.miracleas.com/BAARF/RAID5_versus_RAID10.txt

http://www.miracleas.com/BAARF/1.Millsap2000.01.03-RAID5.pdf

quarta-feira, 20 de agosto de 2014

Microsoft ASP.NET MVC– A história até agora

Introdução

Este artigo apresenta uma visão rápida da história do ASP.NET MVC e dos recursos e funcionalidades mais importantes, introduzidos nas principais versões.

Este será o primeiro de uma série de artigos dedicados ao ASP.NET MVC. Constitui apenas uma pequena introdução, recomendando-se a consulta da vasta documentação online sobre o tema, começando pela página oficial da Microsoft, aqui.

Conteúdo

ASP.NET MVC 1.0 (2009)

A primeira versão oficial foi lançada em 2009 e trouxe todas as características fundamentais da framework, que perduram até hoje:

  • Para começar, o próprio conceito de MVC, com o pipeline simplificado de processamento e separação do processamento do pedido (no Controller) e a renderização do output (na View);
  • O conceito de Routing (que foi incorporado, de seguida, na Framework .NET);
  • Helpers simples para renderizar tags HTML;
  • Helpers para criar facilmente links e forms AJAX;
  • Ligação automática de formulários submetidos (posted forms) a objetos .NET e uma espécie de validação do modelo.

Este foi um grande passo em direção a uma nova web, mas a primeira versão obrigava a demasiado desenvolvimento de infra-estrutura, por forma a ser produtivo em cenários empresariais e em grandes aplicações.

O ASP.NET MVC foi também o primeiro produto da Microsoft a ser realmente extensível. A maioria dos componentes do núcleo podiam ser estendidos ou mesmo totalmente substituídos por implementações próprias.

ASP.NET MVC 2 (2010)

No ano seguinte, foi lançada a segunda versão da framework ASP.NET MVC. O foco desta atualização foi aumentara a produtividade e  facilitar a manutenção nas grandes aplicações:

  • Validação do modelo com base em atributos, tanto do lado do servidor como do lado do cliente;
  • Introdução das Areas, para particionar as grandes aplicações;
  • Html Templated Helpers, para renderizar automaticamente formulários de edição e páginas de exibição, com base no modelo e nos atributos aplicados sobre o mesmo;
  • Controladores assíncronos;
  • HTML Helpers baseados em Expressões Lambda para remover a maioria das “strings mágicas” anteriormente necessárias nos Html Helpers.

ASP.NET MVC 3 (2011)



No início de 2011, foi lançada a versão 3 do ASP.NET MVC, juntamente com uma pilha de outras ferramentas muito interessantes, como o NuGet, IIS Express e SQL Server Express.

As novidades introduzidas nesta versão foram:

  • Só funciona em .NET 4;
  • Novos modelos de projecto, com suporte para HTML5 e CSS3;
  • Validação com unobtrusive javascript e melhor desempenho geral do javascript;
  • Validação remota e melhoria geral da validação do modelo;
  • Dependency Resolver incorporado;
  • Razor: o novo motor para Views;
  • Suporte para vários motores para Views, i.e., Web Forms, Razor ou open source;
  • Melhorias do controlador como a propriedade ViewBag e tipos de ActionResults;
  • Filtros globais;
  • Cache de output para página parcial.

ASP.NET MVC 4 (2012)




Em 2012, é lançada a versão 4 do ASP.NET MVC com algumas novidades significativas:

  • ASP.NET Web API, uma framework que simplifica a criação de serviços HTTP e serve uma grande variedade de clientes;
  • Renderização adaptável e outras melhorias “look-n-feel” nos modelos padrão de projeto;
  • Um modelo de projeto verdadeiramente vazio;
  • Introduzido novo modelo de projecto Mobile, baseado em jQuery Mobile;
  • Suporte para adicionar controladores de outras pastas de projecto;
  • Controlo de tarefas para controladores assíncronos;
  • Controlo de Bundling and Minification através de web.config;
  • Suporte para logins  OAuth e OpenID com a biblioteca DotNetOpenAuth;
  • Suporte para o Windows Azure SDK 1.6 e posteriores.

ASP.NET MVC 5 (2013)



No último trimestre de 2013 foi lançada a versão 5 do ASP.NET MVC, que passou a ser a versão standard de MVC do Visual Studio 2013. As principais novidades introduzidas foram:

  • O Bootstrap substitui o modelo padrão MVC;
  • ASP.NET Identity para autenticação e gestão de identificação;
  • Authentication Filters para autenticação customizada de utilizador ou por provedor de autenticação de terceiros;
  • É agora possível substituir filtros num método ou controlador;
  • O Attribute Routing está agora integrado no MVC 5.

ASP.NET MVC 5.1 (Janeiro 2014)

  • Melhorias no Attribute Routing;
  • Suporte para tipos Enum nas Views;
  • Suporte para Bootstrap nos modelos de editores;
  • Validação não intrusiva para os atributos de modelo MinLengthAttribute e MaxLengthAttribute;
  • Suporte para o contexto this no Unobtrusive Ajax.

ASP.NET MVC 5.2 (Julho 2014)

  • Melhorias no Attribute Routing.

Todas as versões do ASP.NET MVC

A título de curiosidade lista de todas as versões do ASP.NET MVC, lançadas pela Microsoft, é a seguinte:

Data
Versão
2007-12-10
ASP.NET MVC CTP
2009-03-13
ASP.NET MVC 1.0   (download)
2009-12-06
ASP.NET MVC 2 RC
2010-02-04
ASP.NET MVC 2 RC 2
2010-03-10
ASP.NET MVC 2   (download)
2010-10-06
ASP.NET MVC 3 Beta
2010-11-09
ASP.NET MVC 3 RC
2010-12-10
ASP.NET MVC 3 RC 2
2011-01-13
ASP.NET MVC 3   (download)
2011-09-20
ASP.NET MVC 4 Developer Preview
2012-02-15
ASP.NET MVC 4 Beta
2012-05-31
ASP.NET MVC 4 RC
2012-08-15
ASP.NET MVC 4   (download)
2013-05-30
ASP.NET MVC 4 4.0.30506.0
2013-06-26
ASP.NET MVC 5 Preview
2013-08-23
ASP.NET MVC 5 RC 1 [a]
2013-10-17
ASP.NET MVC 5 [a]
2014-01-17
ASP.NET MVC 5.1 [a]
2014-02-10
ASP.NET MVC 5.1.1 [a]
2014-04-04
ASP.NET MVC 5.1.2 [a]
2014-06-22
ASP.NET MVC 5.1.3 [a]
2014-07-01
ASP.NET MVC 5.2.0 [a]

[a] http://www.nuget.org/packages/Microsoft.AspNet.Mvc

O custo do Código Morto

As Funcionalidades Vestigiais (no sentido da evolução dos sistemas) são uma praga comum no software e há um tipo especial dessas funcionalidades que muitas vezes passa despercebido.

Geralmente as Funcionalidades Vestigiais são recursos utilizáveis que, simplesmente, não são usados. Mas, internamente, cada sistema tem partes de código que não são sequer expostas, que não suportam funcionalidades a que os utilizadores possam aceder. São muitas vezes o resultado de experiências, ou de uma funcionalidade vestigial que não foi totalmente eliminada. Vamos referir-nos a isto como código morto.

Um pouco de código morto não é um problema. No entanto, quando a quantidade cresce, pode rapidamente sair fora de controlo. E o código morto tende a aumentar, não a diminuir. Porquê? Porque a maioria dos programadores têm medo de remover código. Eles preferem entrar, fazer as suas alterações e sair. Tudo de forma a perturbar o sistema o mínimo possível.

Há muitas razões para isto:

  • Eles podem não entender o que é suposto o sistema fazer;
  • Pode não haver uma explicação calara sobre o que o sistema deve fazer;
  • Eles podem não saber o que é o que não é código morto;
  • Podem não existir testes suficientes para os ajudar a ter confiança de que não estão a eliminar algo importante;
  • Provavelmente não lhes é dado o tempo necessário para pesquisar e remover o código morto;
  • E se alguma vez o programador cometer um erro no processo de tentar limpar parte do lixo interno, será castigado.

A maioria dos sistemas de controlo de versão são tão avançados que qualquer mudança ao sistema está acessível instantaneamente, mesmo sem uma conexão à internet. No entanto, é cada vez mais comum ver os programadores a comentar ou deixar código morto para trás, em vez de removê-lo. Para muitos programadores, simplesmente não há incentivo para remover código morto e, em vez disso, todos os motivos para não o fazer. É por isso que tende a crescer.

Mas por que isto é importante? É importante porque é a desordem. Se já visitou a casa de alguém que acumula coisas, consegue imaginar o que será estudar uma base de código que está cheio de código morto. Imagine que precisa encontrar alguma coisa na casa de um colecionador. Vai demorar um bocado. A mesma coisa acontece quando tentamos alterar código que está a transbordar de código morto. O código morto fica no caminho do código útil.

O código morto nem sempre é óbvio. E tem uma grande tendência para afectar o modo como os programadores acham que o sistema realmente funciona. Muitas vezes, é necessário estudar o sistema detalhadamente para o conseguir descobrir. Sem tempo para fazer este estudo, o código morto concorre com a capacidade mental de entender como um sistema funciona.

Código morto gera código morto. Código morto frequentemente usa outro código. Este código, por sua vez, pode ser código morto, se é usado apenas por outro código morto. Pense na casa do colecionador. Naquele conjunto extra de prateleiras, para guardar todas as coisas que nunca vai usar. Esse conjunto extra de prateleiras não seria necessário se não fosse por causa da desordem.

Mas não é apenas a desordem. Porque é difícil reconhecer o código morto, os programadores vão fazer tudo para o proteger, assim como ao resto do código útil do sistema. E justamente por isso, eles não querem ser imprudentes.

A posse não vem sem um custo. O código morto custa dinheiro real para manter.

O código morto torna difícil alterar um sistema. O Refactoring, ou a reescrita, é muito mais difícil se tiver que considerar o impacto do código morto. Os componentes críticos do sistema são constrangidos por código morto. Estes constrangimentos causam dificuldades na adaptação a novas funcionalidades. O código morto tende a cristalizar e nunca mudar, ancorando assim outras partes do sistema, de forma análoga à fixação de um barco.

Por outro lado, as consequências secundárias podem ser desastrosos. O código morto pode ser usado acidentalmente quando alguém altera o sistema no futuro. Porque é código morto, é altamente improvável que ele se comporte como esperado. Provavelmente está incompleto e, definitivamente, não foi bem testado. Consequentemente, a sua utilização pode ** introduzir defeitos*.

Como eliminar o Código Morto 

Felizmente, é bastante fácil de limpar o código morto.

Ao crescer, adorei participar em acampamentos de fim de semana, como Escoteiro. Depois de um fim de semana divertido, fazíamos o nosso melhor para deixar o acampamento melhor do que o encontramos.

Depois de um árduo dia de trabalho, deixe o seu código um pouco melhor do que o encontrou.

Se toda a gente comprar essa filosofia, os esforços serão recompensados. Os programadores devem manter a vista fora do código morto. Os gestores devem apoiar, e não desanimar, os programadores. Antes que se perceba, o código morto desaparecerá. De seguida, podemos passar a problemas maiores.

O código morto explicado de forma simples

Tradução livre do artigo “The cost of dead code and the only technique you need to know to clean it up”, de Wes McClure.

segunda-feira, 11 de agosto de 2014

Mecanismo de Globalização de Base de Dados

Introdução

Hoje em dia a maioria das aplicações que utilizamos (principalmente as baseadas na Internet) permitem a apresentação do seu user interface (UI) em várias línguas. Esta é uma das funcionalidades de internacionalização e localização de aplicações.

Também é comum as aplicações terem conteúdos dinâmicos (como opções de menu, links, listas de opções, etc.), que podem estar guardados numa Base de Dados (BD). Se a aplicação for globalizada, então é necessário termos os conteúdos provenientes da BD em várias línguas também.

Neste artigo vamos analisar um mecanismo que permite guardar conteúdos em múltiplas línguas, numa BD e fazer a sua leitura de uma forma consistente e automática, na língua pretendida.

Scripts: todos os scripts com os exemplos deste artigo podem ser encontrados aqui.

Conteúdo

Compreender o problema

Num mundo globalizado como o actual, é essencial desenvolver aplicações globalizadas, i.e. que possuam mecanismos automáticos de internacionalização e localização.

Neste contexto, entende-se globalização como a capacidade das aplicações apresentarem mensagens em diferentes línguas e culturas (moeda, formato números, unidades medida, etc.), dependendo da localização do utilizador.

As diversas tecnologias e frameworks de programação de software têm apresentado, ao longo do tempo, mecanismos de globalização que permitem, com relativa facilidade, apresentar mensagens localizadas, conforme o objectivo mencionado no parágrafo anterior. Tipicamente, os textos das mensagens são colocados em ficheiros de resources separados por cada Língua/Cultura (p.ex. pt-PT=Português de Portugal ou pt-BR= Português do Brasil), que são chamados automaticamente, conforme a cultura activa.

Estes mecanismos funcionam para textos que estejam embebidos no próprio código fonte das aplicações. Todavia, é comum as aplicações terem textos e conteúdos dinâmicos  guardados em BD. Vejamos dois exemplos:

  • Uma dada aplicação tem menus dinâmicos, cujas opções dependem da licença de software e do perfil de cada utilizador. As várias opções dos menus (etiqueta a apresentar, perfil de acesso, recursos, etc.) estão guardadas na BD.
  • Numa dada aplicação é pedido ao utilizador que preencha os seus dados pessoais, existindo alguns campos em que tem que escolher um valor duma lista, como p.ex. estado civil, regime casamento, género, tipo de documento identificação, habilitações literárias, etc. Estas listas de valores estão guardadas em tabelas na BD.

No primeiro caso temos as etiquetas das opções dos menus que necessitam ser globalizadas, no segundo caso, temos dados de referência (as listas de valores) que necessitam ser globalizadas, também.

A questão que se coloca é como fazer a globalização destes dados, guardados em BD.

Visão geral

Com este mecanismo, a BD mantém a estrutura das tabelas originais, com os dados de negócio. Estas tabelas vão conter os dados no idioma e cultura neutro ou por defeito (para o presente artigo, vamos considerar que é pt-PT).

Vai ser criada uma tabela adicional, que regista as informações localizadas para os campos das outras tabelas, que necessitem tradução.

Como alternativa a ter uma única tabela com a informação localizada para TODAS as outras tabelas, esta pode ser dividida por várias tabelas, dependendo, por exemplo, da área funcional. Em qualquer dos casos, deve sempre ser muito claro qual a tabela de localização a utilizar.

As principais vantagens deste método são as seguintes:

  • Tem pouco impacto sobre o desenvolvimento da aplicação, porque toda a selecção da localização pode ser realizada na BD. A única questão é que todas as consultas à BD devem ser realizadas por meio de uma Stored Procedure (SP), com o código de cultura como parâmetro;
  • O método de localização permite utilizar valores predefinidos ou por defeito, que geralmente são os valores da tabela principal;
  • Apenas os dados localizados são registados, nenhum dado desnecessário é replicado;
  • É muito fácil mudar para uma abordagem não globalizada. Consultam-se simplesmente os dados das tabelas principais e não se utiliza a tabela localizada.

Objectos de Base de Dados utilizados pelo Mecanismo

Este método pode ser aplicado a qualquer tido de BD. Para efeitos da descrição e dos exemplos apresentados neste artigo, vamos utilizar o Microsoft SQL Server.

Objecto Tipo Descrição
CultureInfo Tabela
Esta tabela irá registar as informações de referência para os idiomas e culturas disponíveis no sistema.
Todos os dados localizados devem ter uma chave externa com o identificador de cultura obtido desta tabela.
ObjectGlobalization Tabela
Esta tabela irá registar a informação localizada para todas as tabelas na base de dados, utilizando um modelo EAV (Modelo Entidade Atributo Valor).
Cada linha tem uma chave que identifica a tabela, a coluna, a cultura e o Id da linha para os dados localizados.
GetGlobalizedValue Função
Esta é uma função auxiliar que permite ler o valor localizado a partir da tabela anterior, utilizando os campos-chave como parâmetros.
GetGlobalizedTextValue Função
Esta função é uma variação da função anterior que lê apenas valores de texto (nvarchar).
usp_SaveGlobalizedValue SP
Esta é uma SP auxiliar, para guardar os dados localizados na tabela ObjectGlobalization

Tabela CultureInfo

CultureName DisplayName ISO_639x_Value Culturecode
af-ZA Afrikaans - South Africa 0x0436 AFK
ar-AE Arabic - United Arab Emirates 0x3801 ARU
ar-BH Árabe - Bahrain 0x3C01 ARH
ar-DZ Árabe - Algeria 0x1401 ARG

O conteúdo da tabela CultureInfo é trivial.

Tabela ObjectLocalization

ObjectName ColumnName Culture RowId Value
dbo.PortType Name pt-PT 1 Porto Marítimo
dbo.PortType Name pt-PT 2 Porto Seco
GLOBAL_VALUE Description en-US 0 No
GLOBAL_VALUE Description en-US 1 Yes
GLOBAL_VALUE Description en-US All All
GLOBAL_VALUE Description pt-PT 0 Não
GLOBAL_VALUE Description pt-PT 1 Sim
GLOBAL_VALUE Description pt-PT All Todos

Coluna Tipo Descrição
ObjectName Varchar(128)
Normalmente esta coluna regista o Nome de tabela.
Para casos especiais, pode utilizar um nome de convenção, como GLOBAL_VALUE
ColumnName Varchar(128) Este é o nome da coluna que deseja localizar
Culture Varchar(10) Esta é a chave externa para a tabela CultureInfo
RowId Sql_Variant
Regista o valor na coluna de Id da linha na tabela original. Este valor de Id pode ser qualquer tipo de dados do SQL.
Value Sql_Variant Esta coluna regista o valor localizado
ValueText Varchar(max)
Esta coluna regista o valor de texto localizado. Ela pode ser utilizada como uma alternativa à coluna de valor
ValueXML XML
Esta coluna regista o valor localizado XML. Ela pode ser utilizada como uma alternativa à coluna de valor também

Sempre que for necessário criar um valor localizado, basta inserir uma nova linha na tabela ObjectGlobalization com o nome da tabela, o nome da coluna e o valor de Id para identificar a linha e o valor localizado. Existe uma SP para executar esta tarefa.

Function GetGlobalizedValue

Parâmetro Tipo Descrição
@ObjectName Varchar(128)
O nome do objecto a pesquisar na tabela ObjectGlobalization
@ColumnName Varchar(128) O nome da coluna a pesquisar na tabela ObjectGlobalization
@Culture Varchar(10) O nome da cultura a pesquisar na tabela ObjectGlobalization
@RowId Sql_Variant O Id da linha a pesquisar na tabela ObjectGlobalization
@Default Sql_Variant
Este é o valor por defeito, opcional, para a função, se a consulta sobre a tabela ObjectGlobalization não retornar dados. É tipicamente o valor da tabela original (cultura predefinida)

Exemplos de utilização:

SELECT GetGlobalizedValue('PortType', 'Name', 'fr-FR', PortTypeId, PortTypeName)
FROM PortType

Este exemplo lê o valor localizado, em Francês, da coluna Name da tabela PortType, utilizando o valor da coluna PortTypeName original como valor predefinido.

SET @label=GetGlobalizedValueText('GLOBAL_VALUE', 'Name', 'pt-PT', 'All', 'All')

Este exemplo define a variável @label para o valor localizado em Português da string 'All' com o valor em Inglês predefinido.

Neste caso, o nome de objecto, nome de coluna e identificador de linha são convenções, uma vez que não é um valor de uma tabela.

Function GetGlobalizedValueText

Faz o mesmo que a função anterior, com a única diferença de que o valor retornado é obtido a partir da coluna ValueText na tabela ObjectGlobalization.

Stored Procudure usp_SaveGlobalizedValue

Faz o mesmo que a função anterior, com a única diferença de que o valor retornado é obtido a partir da coluna ValueText na tabela ObjectGlobalization.

Parâmetro Tipo Descrição
@ObjectName Varchar(128) O nome do objecto a registar na tabela ObjectGlobalization
@ColumnName Varchar(128) O nome da coluna a registar na tabela ObjectGlobalization
@Culture Varchar(10) O nome da cultura a registar na tabela ObjectGlobalization
@RowId Sql_Variant O Id da linha a registar na tabela ObjectGlobalization
@Value Sql_Variant
O valor localizado para coluna especificada a registar na tabela ObjectGlobalization
@ValueText Varchar(max)
Um valor de texto localizado alternativo, para a coluna especificada, a registar na tabela ObjectGlobalization. Em casos práticos, este será o valor usado principalmente.
@ValueXml XML
Um valor XML localizado alternativo, para a coluna especificada, a registar na tabela ObjectGlobalization
@username Varchar(10)
Um parâmetro opcional para registar o nome do utilizador responsável pelo registo da informação localizada. Se este parâmetro não for especificado, o utilizador do sistema será registado.

Quando for necessário criar ou actualizar um registo na tabela ObjectGlobalization deve-se utilizar esta SP.

Exemplos de utilização:

EXEC    [dbo].[SaveGlobalizedValue]
        @ObjectName = 'PortType',
        @ColumnName = 'Name',
        @Culture     = 'fr-FR',
        @RowID     = 333,
        @Value     = NULL,
        @ValueText     = 'Port au Prince',
        @ValueXml     = NULL,
        @username     = 'kzinga'

Este exemplo regista (ou actualiza) a informação localizada para um dos valores em Francês que seriam lidos no exemplo anterior na função GetGlobalizedValue.

Considerações alternativas

Existem vários métodos de localização de BD, que podem ser tipificados nas secções que se seguem.

Embora cada um destes métodos apresente as suas vantagens, existem algumas desvantagens significativas em comparação com o método de Globalização de Objectos apresentado anteriormente.

Base de Dados Clone

Utilizando este método cria-se um clone completo da BD. O resultado é uma cópia exacta da estrutura original, incluindo todas as tabelas e campos. As BDs diferem apenas no nome e os conteúdos em diferentes idiomas.

Este método tem as desvantagens de exigir uma gestão complexa de conexões e uma duplicação desnecessária de dados (de todos os campos não localizados).

Field Database Localization

Utilizando este método, os valores dos campos localizados são criados na mesma linha da tabela. Os campos localizados são iguais ao campo original, com a excepção de conterem dados num idioma diferente e, é claro, os seus nomes diferem.

A principal desvantagem consiste no facto de que o código deve escolher dinamicamente a coluna com base no idioma selecionado e, claro, parece uma boa solução quando se começa com 2 idiomas, mas se o sistema cresce e precisar de um 3 º idioma? E um 4º? …

Linha Clone

Cada linha da tabela original é copiada para cada idioma. As linhas copiadas são iguais ao original, com a excepção de o valor do campo de idioma ser diferente. O resultado pode ter esta visualização:

As principais desvantagens são que, embora tenha pequeno impacto sobre o desenvolvimento da aplicação (o idioma é usado como chave para selecionar a linha e não na coluna) o conteúdo da tabela vai crescer e vai aumentar a complexidade de administrá-la.

Tabela Clone

Este método adiciona tabelas localizadas para as tabelas que se deseja localizar. As tabelas localizadas contêm somente a chave primária e os campos que são localizados. O resultado é escrito nas novas tabelas com a mesma estrutura. As tabelas de base de dados só têm nomes diferentes, como Descricao e Descricao_ja:

Outra opção para este método é ter a tabela original com todos os campos e a tabela localizada apenas com códigos de idioma e os campos localizados. É uma espécie do exemplo de Linha Clone, mas com as linhas localizadas numa tabela separada.

Tal como o método de localização de campo, a principal desvantagem é que o código deve escolher dinamicamente o nome de tabela com base no idioma selecionado. E se o número de idiomas utilizados pelo sistema começar a crescer, acabará com um número excessivo de tabelas.

Referências

http://www.sisulizer.com/localization/software/server-desktop-database.shtml

http://www.sqlservercentral.com/Forums/Topic205432-230-1.aspx