U-SQL programlama kılavuzuna genel bakış
Önemli
Azure Data Lake Analytics 29 Şubat 2024'te kullanımdan kaldırıldı. Bu duyuru ile daha fazla bilgi edinin.
Veri analizi için kuruluşunuz Azure Synapse Analytics veya Microsoft Fabric kullanabilir.
U-SQL, büyük veri türü iş yükleri için tasarlanmış bir sorgu dilidir. U-SQL'in benzersiz özelliklerinden biri, SQL benzeri bildirim temelli dilin C# tarafından sağlanan genişletilebilirlik ve programlanabilirlik ile birleşimidir. Bu kılavuzda, C# tarafından etkinleştirilen U-SQL dilinin genişletilebilirliğine ve programlanabilirliğine odaklanacağız.
Gereksinimler
Visual Studio için Azure Data Lake Araçları indirip yükleyin.
U-SQL kullanmaya başlama
Aşağıdaki U-SQL betiğine bakın:
@a =
SELECT * FROM
(VALUES
("Contoso", 1500.0, "2017-03-39"),
("Woodgrove", 2700.0, "2017-04-10")
) AS D( customer, amount, date );
@results =
SELECT
customer,
amount,
date
FROM @a;
Bu betik iki RowSet tanımlar: @a
ve @results
. RowSet @results
dosyasından @a
tanımlanır.
U-SQL betiğindeki C# türleri ve ifadeleri
U-SQL İfadesi, , OR
ve NOT
gibi AND
U-SQL mantıksal işlemleriyle birleştirilmiş bir C# ifadesidir. U-SQL İfadeleri SELECT, EXTRACT, WHERE, HAVING, GROUP BY ve DECLARE ile kullanılabilir. Örneğin, aşağıdaki betik bir dizeyi DateTime değeri olarak ayrıştırır.
@results =
SELECT
customer,
amount,
DateTime.Parse(date) AS date
FROM @a;
Aşağıdaki kod parçacığı, bir dizeyi DECLARE deyiminde DateTime değeri olarak ayrıştırır.
DECLARE @d = DateTime.Parse("2016/01/01");
Veri türü dönüştürmeleri için C# ifadelerini kullanma
Aşağıdaki örnekte, C# ifadelerini kullanarak tarih saat veri dönüştürme işlemini nasıl yapabileceğiniz gösterilmektedir. Bu özel senaryoda, datetime verileri dizesi gece yarısı 00:00:00 saat gösterimiyle standart tarih saatine dönüştürülür.
DECLARE @dt = "2016-07-06 10:23:15";
@rs1 =
SELECT
Convert.ToDateTime(Convert.ToDateTime(@dt).ToString("yyyy-MM-dd")) AS dt,
dt AS olddt
FROM @rs0;
OUTPUT @rs1
TO @output_file
USING Outputters.Text();
Bugünün tarihi için C# ifadelerini kullanma
Bugünün tarihini çekmek için aşağıdaki C# ifadesini kullanabiliriz: DateTime.Now.ToString("M/d/yyyy")
Aşağıda bu ifadenin betikte nasıl kullanılacağına yönelik bir örnek verilmişti:
@rs1 =
SELECT
MAX(guid) AS start_id,
MIN(dt) AS start_time,
MIN(Convert.ToDateTime(Convert.ToDateTime(dt<@default_dt?@default_dt:dt).ToString("yyyy-MM-dd"))) AS start_zero_time,
MIN(USQL_Programmability.CustomFunctions.GetFiscalPeriod(dt)) AS start_fiscalperiod,
DateTime.Now.ToString("M/d/yyyy") AS Nowdate,
user,
des
FROM @rs0
GROUP BY user, des;
.NET derlemelerini kullanma
U-SQL'in genişletilebilirlik modeli büyük ölçüde .NET derlemelerinden özel kod ekleme özelliğine dayanır.
.NET derlemesi kaydetme
CREATE ASSEMBLY
U-SQL Veritabanı içine bir .NET derlemesi yerleştirmek için deyimini kullanın. Daha sonra U-SQL betikleri deyimini REFERENCE ASSEMBLY
kullanarak bu derlemeleri kullanabilir.
Aşağıdaki kod, bir derlemenin nasıl kaydedileceklerini gösterir:
CREATE ASSEMBLY MyDB.[MyAssembly]
FROM "/myassembly.dll";
Aşağıdaki kod, bir derlemeye nasıl başvuracaklarını gösterir:
REFERENCE ASSEMBLY MyDB.[MyAssembly];
Bu konuyu daha ayrıntılı bir şekilde kapsayan derleme kayıt yönergelerine başvurun.
Derleme sürümü oluşturma kullanma
U-SQL şu anda .NET Framework 4.7.2 sürümünü kullanmaktadır. Bu nedenle kendi derlemelerinizin çalışma zamanının bu sürümüyle uyumlu olduğundan emin olun.
Daha önce belirtildiği gibi, U-SQL kodu 64 bit (x64) biçiminde çalıştırır. Bu nedenle kodunuzun x64 üzerinde çalışacak şekilde derlendiğinden emin olun. Aksi takdirde, daha önce gösterilen yanlış biçim hatasını alırsınız.
Karşıya yüklenen her derleme DLL'i ve farklı bir çalışma zamanı, yerel derleme veya yapılandırma dosyası gibi kaynak dosyaları en fazla 400 MB olabilir. DAĞıTıLAN kaynakların toplam boyutu( DEPLOY RESOURCE veya derlemelere ve diğer dosyalarına başvurular yoluyla) 3 GB'ı aşamaz.
Son olarak, her U-SQL veritabanı belirli bir derlemenin yalnızca bir sürümünü içerebilir. Örneğin, NewtonSoft Json.NET kitaplığının hem sürüm 7 hem de sürüm 8'e ihtiyacınız varsa, bunları iki farklı veritabanına kaydetmeniz gerekir. Ayrıca, her betik belirli bir derleme DLL'sinin yalnızca bir sürümüne başvurabilir. Bu açıdan U-SQL, C# derleme yönetimi ve sürüm oluşturma semantiğini izler.
Kullanıcı tanımlı işlevleri kullanma: UDF
U-SQL kullanıcı tanımlı işlevler veya UDF, parametreleri kabul eden, bir eylem gerçekleştiren (karmaşık bir hesaplama gibi) ve bu eylemin sonucunu değer olarak döndüren programlama yordamlarıdır. UDF'nin dönüş değeri yalnızca tek bir skaler olabilir. U-SQL UDF, diğer C# skaler işlevleri gibi U-SQL temel betiğinde çağrılabilir.
U-SQL kullanıcı tanımlı işlevleri genel ve statik olarak başlatmanızı öneririz.
public static string MyFunction(string param1)
{
return "my result";
}
İlk olarak UDF oluşturmanın basit örneğine bakalım.
Bu kullanım örneği senaryosunda, belirli bir kullanıcı için ilk oturum açma işleminin mali çeyreği ve mali ayı da dahil olmak üzere mali dönemi belirlememiz gerekir. Senaryomuzda yılın ilk mali ayı Haziran ayıdır.
Mali dönemi hesaplamak için aşağıdaki C# işlevini tanıtacağız:
public static string GetFiscalPeriod(DateTime dt)
{
int FiscalMonth=0;
if (dt.Month < 7)
{
FiscalMonth = dt.Month + 6;
}
else
{
FiscalMonth = dt.Month - 6;
}
int FiscalQuarter=0;
if (FiscalMonth >=1 && FiscalMonth<=3)
{
FiscalQuarter = 1;
}
if (FiscalMonth >= 4 && FiscalMonth <= 6)
{
FiscalQuarter = 2;
}
if (FiscalMonth >= 7 && FiscalMonth <= 9)
{
FiscalQuarter = 3;
}
if (FiscalMonth >= 10 && FiscalMonth <= 12)
{
FiscalQuarter = 4;
}
return "Q" + FiscalQuarter.ToString() + ":P" + FiscalMonth.ToString();
}
Yalnızca mali ayı ve üç aylık dönemi hesaplar ve bir dize değeri döndürür. İlk mali çeyreğin ilk ayı olan Haziran için "Q1:P1" kullanırız. Temmuz için "Q1:P2" vb. kullanırız.
Bu, U-SQL projemizde kullanacağımız normal bir C# işlevidir.
Bu senaryoda arka planda kod bölümü şöyle görünür:
using Microsoft.Analytics.Interfaces;
using Microsoft.Analytics.Types.Sql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace USQL_Programmability
{
public class CustomFunctions
{
public static string GetFiscalPeriod(DateTime dt)
{
int FiscalMonth=0;
if (dt.Month < 7)
{
FiscalMonth = dt.Month + 6;
}
else
{
FiscalMonth = dt.Month - 6;
}
int FiscalQuarter=0;
if (FiscalMonth >=1 && FiscalMonth<=3)
{
FiscalQuarter = 1;
}
if (FiscalMonth >= 4 && FiscalMonth <= 6)
{
FiscalQuarter = 2;
}
if (FiscalMonth >= 7 && FiscalMonth <= 9)
{
FiscalQuarter = 3;
}
if (FiscalMonth >= 10 && FiscalMonth <= 12)
{
FiscalQuarter = 4;
}
return "Q" + FiscalQuarter.ToString() + ":" + FiscalMonth.ToString();
}
}
}
Şimdi bu işlevi temel U-SQL betiğinden çağıracağız. Bunu yapmak için ad alanı da dahil olmak üzere işlev için ad alanını içeren tam bir ad sağlamamız gerekir. Bu örnekte NameSpace.Class.Function(parametre).
USQL_Programmability.CustomFunctions.GetFiscalPeriod(dt)
Gerçek U-SQL temel betiği aşağıdadır:
DECLARE @input_file string = @"\usql-programmability\input_file.tsv";
DECLARE @output_file string = @"\usql-programmability\output_file.tsv";
@rs0 =
EXTRACT
guid Guid,
dt DateTime,
user String,
des String
FROM @input_file USING Extractors.Tsv();
DECLARE @default_dt DateTime = Convert.ToDateTime("06/01/2016");
@rs1 =
SELECT
MAX(guid) AS start_id,
MIN(dt) AS start_time,
MIN(Convert.ToDateTime(Convert.ToDateTime(dt<@default_dt?@default_dt:dt).ToString("yyyy-MM-dd"))) AS start_zero_time,
MIN(USQL_Programmability.CustomFunctions.GetFiscalPeriod(dt)) AS start_fiscalperiod,
user,
des
FROM @rs0
GROUP BY user, des;
OUTPUT @rs1
TO @output_file
USING Outputters.Text();
Betik yürütmesinin çıkış dosyası aşağıdadır:
0d8b9630-d5ca-11e5-8329-251efa3a2941,2016-02-11T07:04:17.2630000-08:00,2016-06-01T00:00:00.0000000,"Q3:8","User1",""
20843640-d771-11e5-b87b-8b7265c75a44,2016-02-11T07:04:17.2630000-08:00,2016-06-01T00:00:00.0000000,"Q3:8","User2",""
301f23d2-d690-11e5-9a98-4b4f60a1836f,2016-02-11T09:01:33.9720000-08:00,2016-06-01T00:00:00.0000000,"Q3:8","User3",""
Bu örnekte U-SQL'de satır içi UDF'nin basit kullanımı gösterilmektedir.
UDF çağrıları arasında durumu koruma
U-SQL C# programlanabilirlik nesneleri, kod arkası genel değişkenleri aracılığıyla etkileşimden yararlanarak daha karmaşık olabilir. Şimdi aşağıdaki iş kullanım örneği senaryosuna göz atalım.
Büyük kuruluşlarda kullanıcılar dahili uygulama türleri arasında geçiş yapabilir. Bunlar Microsoft Dynamics CRM, Power BI vb. içerebilir. Müşteriler, kullanıcıların farklı uygulamalar arasında nasıl geçiş yaptığını, kullanım eğilimlerinin ne olduğunu vb. içeren bir telemetri analizi uygulamak isteyebilir. İşletmenin amacı, uygulama kullanımını iyileştirmektir. Ayrıca farklı uygulamaları veya belirli oturum açma yordamlarını birleştirmek isteyebilirler.
Bu hedefe ulaşmak için oturum kimliklerini ve gerçekleşen son oturum arasındaki gecikme süresini belirlememiz gerekir.
Önceki oturum açma bilgilerini bulmalıyız ve ardından bu oturum açma işlemini aynı uygulamada oluşturulan tüm oturumlara atamalıyız. İlk zorluk, U-SQL temel betiğinin LAG işleviyle önceden hesaplanmış sütunlara hesaplamalar uygulamamıza izin vermemesidir. İkinci zorluk, aynı zaman aralığındaki tüm oturumlar için belirli bir oturumu tutmamız gerekmektir.
Bu sorunu çözmek için arka planda kod bölümü içinde genel bir değişken kullanırız: static public string globalSession;
.
Bu genel değişken betik yürütmemiz sırasında satır kümesinin tamamına uygulanır.
U-SQL programımızın arka planda kod bölümü aşağıdadır:
using Microsoft.Analytics.Interfaces;
using Microsoft.Analytics.Types.Sql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace USQLApplication21
{
public class UserSession
{
static public string globalSession;
static public string StampUserSession(string eventTime, string PreviousRow, string Session)
{
if (!string.IsNullOrEmpty(PreviousRow))
{
double timeGap = Convert.ToDateTime(eventTime).Subtract(Convert.ToDateTime(PreviousRow)).TotalMinutes;
if (timeGap <= 60) {return Session;}
else {return Guid.NewGuid().ToString();}
}
else {return Guid.NewGuid().ToString();}
}
static public string getStampUserSession(string Session)
{
if (Session != globalSession && !string.IsNullOrEmpty(Session)) { globalSession = Session; }
return globalSession;
}
}
}
Bu örnekte, işlevin içinde getStampUserSession
kullanılan genel değişken static public string globalSession;
ve Session parametresi her değiştirildiğinde yeniden başlatılma işlemi gösterilmektedir.
U-SQL temel betiği aşağıdaki gibidir:
DECLARE @in string = @"\UserSession\test1.tsv";
DECLARE @out1 string = @"\UserSession\Out1.csv";
DECLARE @out2 string = @"\UserSession\Out2.csv";
DECLARE @out3 string = @"\UserSession\Out3.csv";
@records =
EXTRACT DataId string,
EventDateTime string,
UserName string,
UserSessionTimestamp string
FROM @in
USING Extractors.Tsv();
@rs1 =
SELECT
EventDateTime,
UserName,
LAG(EventDateTime, 1)
OVER(PARTITION BY UserName ORDER BY EventDateTime ASC) AS prevDateTime,
string.IsNullOrEmpty(LAG(EventDateTime, 1)
OVER(PARTITION BY UserName ORDER BY EventDateTime ASC)) AS Flag,
USQLApplication21.UserSession.StampUserSession
(
EventDateTime,
LAG(EventDateTime, 1) OVER(PARTITION BY UserName ORDER BY EventDateTime ASC),
LAG(UserSessionTimestamp, 1) OVER(PARTITION BY UserName ORDER BY EventDateTime ASC)
) AS UserSessionTimestamp
FROM @records;
@rs2 =
SELECT
EventDateTime,
UserName,
LAG(EventDateTime, 1)
OVER(PARTITION BY UserName ORDER BY EventDateTime ASC) AS prevDateTime,
string.IsNullOrEmpty( LAG(EventDateTime, 1) OVER(PARTITION BY UserName ORDER BY EventDateTime ASC)) AS Flag,
USQLApplication21.UserSession.getStampUserSession(UserSessionTimestamp) AS UserSessionTimestamp
FROM @rs1
WHERE UserName != "UserName";
OUTPUT @rs2
TO @out2
ORDER BY UserName, EventDateTime ASC
USING Outputters.Csv();
İşlev USQLApplication21.UserSession.getStampUserSession(UserSessionTimestamp)
, ikinci bellek satır kümesi hesaplaması sırasında burada çağrılır. Sütunu geçirir UserSessionTimestamp
ve değişene kadar UserSessionTimestamp
değeri döndürür.
Çıkış dosyası aşağıdaki gibidir:
"2016-02-19T07:32:36.8420000-08:00","User1",,True,"72a0660e-22df-428e-b672-e0977007177f"
"2016-02-17T11:52:43.6350000-08:00","User2",,True,"4a0cd19a-6e67-4d95-a119-4eda590226ba"
"2016-02-17T11:59:08.8320000-08:00","User2","2016-02-17T11:52:43.6350000-08:00",False,"4a0cd19a-6e67-4d95-a119-4eda590226ba"
"2016-02-11T07:04:17.2630000-08:00","User3",,True,"51860a7a-1610-4f74-a9ea-69d5eef7cd9c"
"2016-02-11T07:10:33.9720000-08:00","User3","2016-02-11T07:04:17.2630000-08:00",False,"51860a7a-1610-4f74-a9ea-69d5eef7cd9c"
"2016-02-15T21:27:41.8210000-08:00","User3","2016-02-11T07:10:33.9720000-08:00",False,"4d2bc48d-bdf3-4591-a9c1-7b15ceb8e074"
"2016-02-16T05:48:49.6360000-08:00","User3","2016-02-15T21:27:41.8210000-08:00",False,"dd3006d0-2dcd-42d0-b3a2-bc03dd77c8b9"
"2016-02-16T06:22:43.6390000-08:00","User3","2016-02-16T05:48:49.6360000-08:00",False,"dd3006d0-2dcd-42d0-b3a2-bc03dd77c8b9"
"2016-02-17T16:29:53.2280000-08:00","User3","2016-02-16T06:22:43.6390000-08:00",False,"2fa899c7-eecf-4b1b-a8cd-30c5357b4f3a"
"2016-02-17T16:39:07.2430000-08:00","User3","2016-02-17T16:29:53.2280000-08:00",False,"2fa899c7-eecf-4b1b-a8cd-30c5357b4f3a"
"2016-02-17T17:20:39.3220000-08:00","User3","2016-02-17T16:39:07.2430000-08:00",False,"2fa899c7-eecf-4b1b-a8cd-30c5357b4f3a"
"2016-02-19T05:23:54.5710000-08:00","User3","2016-02-17T17:20:39.3220000-08:00",False,"6ca7ed80-c149-4c22-b24b-94ff5b0d824d"
"2016-02-19T05:48:37.7510000-08:00","User3","2016-02-19T05:23:54.5710000-08:00",False,"6ca7ed80-c149-4c22-b24b-94ff5b0d824d"
"2016-02-19T06:40:27.4830000-08:00","User3","2016-02-19T05:48:37.7510000-08:00",False,"6ca7ed80-c149-4c22-b24b-94ff5b0d824d"
"2016-02-19T07:27:37.7550000-08:00","User3","2016-02-19T06:40:27.4830000-08:00",False,"6ca7ed80-c149-4c22-b24b-94ff5b0d824d"
"2016-02-19T19:35:40.9450000-08:00","User3","2016-02-19T07:27:37.7550000-08:00",False,"3f385f0b-3e68-4456-ac74-ff6cef093674"
"2016-02-20T00:07:37.8250000-08:00","User3","2016-02-19T19:35:40.9450000-08:00",False,"685f76d5-ca48-4c58-b77d-bd3a9ddb33da"
"2016-02-11T09:01:33.9720000-08:00","User4",,True,"9f0cf696-c8ba-449a-8d5f-1ca6ed8f2ee8"
"2016-02-17T06:30:38.6210000-08:00","User4","2016-02-11T09:01:33.9720000-08:00",False,"8b11fd2a-01bf-4a5e-a9af-3c92c4e4382a"
"2016-02-17T22:15:26.4020000-08:00","User4","2016-02-17T06:30:38.6210000-08:00",False,"4e1cb707-3b5f-49c1-90c7-9b33b86ca1f4"
"2016-02-18T14:37:27.6560000-08:00","User4","2016-02-17T22:15:26.4020000-08:00",False,"f4e44400-e837-40ed-8dfd-2ea264d4e338"
"2016-02-19T01:20:31.4800000-08:00","User4","2016-02-18T14:37:27.6560000-08:00",False,"2136f4cf-7c7d-43c1-8ae2-08f4ad6a6e08"
Bu örnekte, bellek satır kümesinin tamamına uygulanan arka planda kod bölümü içinde genel değişken kullandığımız daha karmaşık bir kullanım örneği senaryosu gösterilmektedir.