Compartilhar via


Criar tabelas, partições e colunas em um modelo de tabela

Aplica-se a: SQL Server 2016 e posteriores do Analysis Services Azure Analysis Services Fabric/Power BI Premium

Em um modelo tabular, uma tabela consiste em linhas e colunas. As linhas são organizadas em partições para dar suporte à atualização de dados incremental. Uma solução tabular pode dar suporte a vários tipos de tabelas, dependendo de onde os dados são provenientes:

  • Tabelas regulares, em que os dados se originam de uma fonte de dados relacional, por meio do provedor de dados.

  • Tabelas enviadas por push, em que os dados são "enviados por push" para a tabela programaticamente.

  • Tabelas calculadas, em que os dados vêm de uma expressão DAX que faz referência a outro objeto dentro do modelo para seus dados.

No exemplo de código abaixo, definiremos uma tabela regular.

Elementos obrigatórios

Uma tabela deve ter pelo menos uma partição. Uma tabela regular também deve ter pelo menos uma coluna definida.

Cada partição deve ter uma Origem especificando a origem dos dados, mas a origem pode ser definida como nula. Normalmente, a origem é uma expressão de consulta que define uma fatia de dados na linguagem de consulta de banco de dados relevante.

Exemplo de código: criar uma tabela, coluna, partição

As tabelas são representadas pela classe Table (no namespace Microsoft.AnalysisServices.Tabular).

No exemplo a seguir, definiremos uma tabela regular com uma partição vinculada a uma fonte de dados relacional e algumas colunas regulares. Também enviaremos as alterações ao servidor e dispararemos uma atualização de dados que traz os dados para o modelo. Isso representa o cenário mais típico quando você deseja carregar dados de um banco de dados relacional SQL Server em uma solução tabular.

using System; 
using Microsoft.AnalysisServices; 
using Microsoft.AnalysisServices.Tabular; 
 
namespace TOMSamples 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            // 
            // Connect to the local default instance of Analysis Services 
            // 
            string ConnectionString = "DataSource=localhost"; 
 
            // 
            // The using syntax ensures the correct use of the 
            // Microsoft.AnalysisServices.Tabular.Server object. 
            // 
            using (Server server = new Server()) 
            { 
                server.Connect(ConnectionString); 
 
                // 
                // Generate a new database name and use GetNewName 
                // to ensure the database name is unique. 
                // 
                string newDatabaseName = 
                    server.Databases.GetNewName("Database with a Table Definition"); 
 
                // 
                // Instantiate a new  
                // Microsoft.AnalysisServices.Tabular.Database object. 
                // 
                var dbWithTable = new Database() 
                { 
                    Name = newDatabaseName, 
                    ID = newDatabaseName, 
                    CompatibilityLevel = 1200, 
                    StorageEngineUsed = StorageEngineUsed.TabularMetadata, 
                }; 
 
                // 
                // Add a Microsoft.AnalysisServices.Tabular.Model object to the 
                // database, which acts as a root for all other Tabular metadata objects. 
                // 
                dbWithTable.Model = new Model() 
                { 
                    Name = "Tabular Data Model", 
                    Description = "A Tabular data model at the 1200 compatibility level." 
                }; 
 
                // 
                // Add a Microsoft.AnalysisServices.Tabular.ProviderDataSource object 
                // to the data Model object created in the previous step. The connection 
                // string of the data source object in this example  
                // points to an instance of the AdventureWorks2014 SQL Server database. 
                // 
                string dataSourceName = "SQL Server Data Source Example"; 
                dbWithTable.Model.DataSources.Add(new ProviderDataSource() 
                { 
                    Name = dataSourceName, 
                    Description = "A data source definition that uses explicit Windows credentials for authentication against SQL Server.", 
                    ConnectionString = "Provider=SQLNCLI11;Data Source=localhost;Initial Catalog=AdventureWorks2014;Integrated Security=SSPI;Persist Security Info=false", 
                    ImpersonationMode = Microsoft.AnalysisServices.Tabular.ImpersonationMode.ImpersonateAccount, 
                    Account = @".\Administrator", 
                    Password = "P@ssw0rd", 
                }); 
 
                //  
                // Add a table called Individual Customers to the data model 
                // with a partition that points to a [Sales].[vIndividualCustomer] view 
                // in the underlying data source. 
                // 
                dbWithTable.Model.Tables.Add(new Table() 
                { 
                    Name = dbWithTable.Model.Tables.GetNewName("Individual Customers"), 
                    Description = "Individual customers (names and email addresses) that purchase Adventure Works Cycles products online.", 
                    Partitions = { 
                        // 
                        // Create a single partition with a QueryPartitionSource for a query 
                        // that imports all customer rows from the underlying data source. 
                        // 
                        new Partition() { 
                            Name = "All Customers", 
                            Source = new QueryPartitionSource() { 
                                DataSource = dbWithTable.Model.DataSources[dataSourceName], 
                                Query = @"SELECT   [FirstName] 
                                                    ,[MiddleName] 
                                                    ,[LastName] 
                                                    ,[PhoneNumber]  
                                                    ,[EmailAddress] 
                                                    ,[City] 
                                        FROM [Sales].[vIndividualCustomer]", 
                            } 
                        } 
                    }, 
                    Columns = 
                    { 
                        // 
                       // DataColumn objects refer to regular table columns.  
                        // Each DataColumn object corresponds to a column in the underlying data source query. 
                        // 
                        new DataColumn() { 
                            Name = "FirstName", 
                            DataType = DataType.String, 
                            SourceColumn = "FirstName", 
                        }, 
                        new DataColumn() { 
                            Name = "MiddleName", 
                            DataType = DataType.String, 
                            SourceColumn = "MiddleName", 
                        }, 
                        new DataColumn() { 
                            Name = "LastName", 
                            DataType = DataType.String, 
                            SourceColumn = "LastName", 
                        }, 
                        new DataColumn() { 
                            Name = "PhoneNumber", 
                            DataType = DataType.String, 
                            SourceColumn = "PhoneNumber", 
                        }, 
                        new DataColumn() { 
                            Name = "EmailAddress", 
                            DataType = DataType.String, 
                            SourceColumn = "EmailAddress", 
                        }, 
                        new DataColumn() { 
                            Name = "City", 
                            DataType = DataType.String, 
                            SourceColumn = "City", 
                        }, 
                    } 
                }); 
 
                // 
                // Add the new database object to the server's  
                // Databases connection and submit the changes 
                // with full expansion to the server. 
                // 
                server.Databases.Add(dbWithTable); 
 
                //  
                // Request a full refresh to import the data from the data source and 
                // and perform any necessary recalculations. 
                // The refresh operation will be performed with the next 
                // invocation of Model.SaveChanges() or Database.Update(UpdateOptions.ExpandFull). 
                dbWithTable.Model.RequestRefresh(Microsoft.AnalysisServices.Tabular.RefreshType.Full); 
                dbWithTable.Update(UpdateOptions.ExpandFull); 
 
 
                Console.Write("Database "); 
                Console.ForegroundColor = ConsoleColor.Yellow; 
                Console.Write(dbWithTable.Name); 
                Console.ResetColor(); 
                Console.WriteLine(" created successfully."); 
 
                Console.WriteLine("The data model includes the following table definitions:"); 
                Console.ForegroundColor = ConsoleColor.Yellow; 
                foreach (Table tbl in dbWithTable.Model.Tables) 
                { 
                    Console.WriteLine("\tTable name:\t\t{0}", tbl.Name); 
                    Console.WriteLine("\ttbl description:\t{0}", tbl.Description); 
                } 
                Console.ResetColor(); 
                Console.WriteLine(); 
            } 
            Console.WriteLine("Press Enter to close this console window."); 
            Console.ReadLine(); 
        } 
    } 
} 

Partições em uma tabela

As partições são representadas por uma classe de partição (no namespace Microsoft.AnalysisServices.Tabular). A classe Partition expõe uma propriedade Source do tipo PartitionSource , que fornece uma abstração sobre as diferentes abordagens para ingerir dados na partição. Uma instância de partição pode ter uma propriedade Source como nula, indicando que os dados serão enviados por push para a partição enviando partes de dados para o Servidor como parte da API de dados de push exposta pelo Analysis Services. No SQL Server 2016, a classe PartitionSource tem duas classes derivadas que representam maneiras de associar dados a uma partição: QueryPartitionSource e CalculatedPartitionSource.

Colunas em uma tabela

As colunas são representadas por várias classes derivadas da classe base Column (no namespace Microsoft.AnalysisServices.Tabular):

  • DataColumn (para colunas regulares em tabelas regulares)
  • CalculatedColumn (para colunas apoiadas pela expressão DAX)
  • CalculatedTableColumn (para colunas regulares em tabelas calculadas)
  • RowNumberColumn (tipo especial de coluna criado pelo SSAS para cada tabela).

Números de linha em uma tabela

Cada objeto Table em um servidor tem um RowNumberColumn usado para fins de indexação. Não é possível criá-lo ou adicioná-lo explicitamente. A coluna é criada automaticamente quando você salva ou atualiza o objeto:

  • Db. Savechanges

  • Db. Update(ExpandFull)

Ao chamar qualquer um dos métodos, o servidor criará automaticamente a coluna de número de linha, que ficará visível como RowNumberColumn na coleção Columns da tabela.

Tabelas calculadas

As tabelas calculadas são originadas de uma expressão DAX que reutiliza dados de estruturas de dados existentes no modelo ou de associações fora de linha. Para criar uma tabela calculada programaticamente, faça o seguinte:

  • Crie uma Tabela genérica.

  • Adicione uma partição a ela com Source do tipo CalculatedPartitionSource, em que a origem é uma expressão DAX. A origem da partição é o que diferencia uma tabela regular de uma tabela calculada.

Quando você salvar as alterações no servidor, o servidor retornará a lista inferida de CalculatedTableColumns (tabelas calculadas são compostas de colunas de tabela calculada), visíveis por meio da coleção Columns da tabela.

Próxima etapa

Examine as classes usadas para lidar com exceções no TOM: tratamento de erros no TOM