Tüm Ürünler
Search
Belge Merkezi

MaxCompute:UDT'ye genel bakış

Son Güncelleme:Oct 04, 2026

MaxCompute, yeni nesil SQL motoruna dayalı olarak kullanıcı tanımlı türler (UDT) sunar. UDT'ler, SQL ifadelerinde üçüncü taraf programlama dillerinin sınıflarına veya nesnelerine başvurmanıza, yöntemleri çağırmanıza veya veri almanıza olanak tanır.

UDT'leri ne zaman UDF'lere tercih etmelisiniz?

Hem UDT'ler hem de kullanıcı tanımlı işlevler (UDF), MaxCompute SQL'i özel mantıkla genişletir. İş akışınıza göre seçim yapın:

Durum Önerilen yaklaşım
Yerleşik bir Java sınıfı yöntemini doğrudan çağırma (örneğin, Integer.MAX_VALUE) UDT — işlev tanımı gerekmez
Üçüncü taraf bir kitaplığı SQL ifadesinde doğrudan yeniden kullanma UDT — sarmalamadan sınıfı satır içi olarak referans alın
Derlenmiş kaynak dil nesnelerini çok aşamalı işlere dahil etme UDT — aşamalar arası JVM durumunu otomatik olarak kapsüller
Birden fazla projede yeniden kullanılabilir iş mantığı uygulama UDF — açık işlev kaydı paylaşımı kolaylaştırır

Kullanım senaryoları

  • İşlev tanımlamadan Java standart kitaplık yöntemlerini çağırın. Göreviniz, MaxCompute SQL'in yerel olarak sunmadığı yerleşik bir Java sınıfı yöntemi gerektirdiğinde, UDT bu yöntemi ifade içinde doğrudan çağırmanızı sağlar.

  • Üçüncü taraf kitaplıkları satır içi olarak referans alın. Üçüncü taraf kitaplık işlevini bir UDF içine sarmak yerine, sınıfı SQL ifadesinde doğrudan referans alın.

  • Derlenmiş kaynak kodunu SQL'e gömün. Java gibi derleme gerektiren diller için UDT'ler, ayrı bir kayıt adımı olmadan nesnelere ve sınıflara SQL ifadelerinden başvurmanıza olanak tanır. Betik tabanlı alternatifler için bkz. SELECT TRANSFORM.

Ön koşullar

UDT'leri kullanmadan önce şunlardan emin olun:

  • Ortamınızda JDK 1.8 bulunur. JDK 1.8'den sonraki sürümler desteklenmeyebilir.

  • INT gibi türleri kullanıyorsanız yeni veri türlerini etkinleştirin: set odps.sql.type.system.odps2=true;

Çalışma mantığı

Diğer SQL motorlarında bulunan UDT'lerden (genellikle STRUCT türüne benzer şekilde tür takma adları tanımlayan) farklı olarak, MaxCompute UDT'leri bir CREATE TYPE ifadesi gibi çalışır; hem alanlar hem de yöntemler içerir ve DDL yazmadan bunlara SQL'de doğrudan başvurursunuz.

Aşağıdaki örnek farkı göstermektedir. Java'nın java.lang paketinden Integer.MAX_VALUE değerine erişmek için:

UDT kullanarak (doğrudan başvuru):

-- Enable new data types (required for types such as INTEGER).
set odps.sql.type.system.odps2=true;
SELECT java.lang.Integer.MAX_VALUE;

java.lang otomatik olarak içeri aktarıldığından (Java'da olduğu gibi), bu ifade şuna eşdeğerdir:

set odps.sql.type.system.odps2=true;
SELECT Integer.MAX_VALUE;

Sonuç:

+-----------+
| max_value |
+-----------+
| 2147483647 |
+-----------+

UDF kullanarak (karşılaştırma için):

  1. UDF sınıfını yazın:

    package com.aliyun.odps.test;
    public class IntegerMaxValue extends com.aliyun.odps.udf.UDF {
      public Integer evaluate() {
         return Integer.MAX_VALUE;
      }
    }
  2. Derleyin, yükleyin ve kaydedin:

    add jar odps-test.jar;
    create function integer_max_value as 'com.aliyun.odps.test.IntegerMaxValue' using 'odps-test.jar';
  3. Çağırın:

    select integer_max_value();

UDT'ler bu süreci tek bir SQL ifadesine indirger.

Çok aşamalı yürütme

UDT nesneleri MapReduce aşamaları arasında doğal olarak akar. Aşağıdaki örnek, farklı veri kaynaklarından hesaplanan iki BigInteger sütununu birleştirir:

-- Sample data.
@table1 := select * from values ('100000000000000000000') as t(x);
@table2 := select * from values (100L) as t(y);

-- Create an object with the new method.
@a := select new java.math.BigInteger(x) x from @table1;
-- Call a static method.
@b := select java.math.BigInteger.valueOf(y) y from @table2;
-- Call an instance method across the join.
select /*+mapjoin(b)*/ x.add(y).toString() from @a a join @b b;

-- Output:
100000000000000000100

Bu iş üç aşamada (M1, R2, J3) çalışır. new java.math.BigInteger(x) M1'de; java.math.BigInteger.valueOf(y) ve x.add(y).toString() ise farklı süreçlerde ve fiziksel makinelerde J3'te çalışır. UDT, tüm aşamaların aynı Java Sanal Makinesinde (JVM) çalıştığı izlenimini verecek şekilde bunu kapsüller.

Bu UDT örneği SQL işinin DAG'i üç aşama içerir: M1 → R2_1 → J3_2. Tüm aşamalar %100 tamamlanmıştır ve her aşama arasında 1 satır veri iletilir.

a değişkeninden gelen x sütunu, yerleşik bir tür yerine java.math.BigInteger türündedir. Bu UDT değeri diğer operatörlere iletilebilir ve veri karıştırma işlemlerinde kullanılabilir.

JAR paketlerine başvurma ve Java içe aktarmalarını ayarlama

Tüm SDK for Java sınıfları varsayılan olarak UDT'ler tarafından kullanılabilir. Ek JAR paketlerine başvurmak veya varsayılan içe aktarma yollarını ayarlamak için aşağıdaki oturum bayraklarını kullanın.

JAR paketine başvurma:

set odps.sql.type.system.odps2=true;
set odps.sql.session.resources=odps-test.jar;
-- The JAR must be uploaded to the project beforehand.
select new com.aliyun.odps.test.IntegerMaxValue().evaluate();

Virgülle ayrılmış birden fazla kaynak belirtebilirsiniz: set odps.sql.session.resources=foo.sh,bar.txt;

odps.sql.session.resources hem UDT'leri hem de SELECT TRANSFORM'u kontrol eder. Burada ayarlanan bir JAR, her iki özellik için de kullanılabilir.

Varsayılan Java içe aktarma yolunu ayarlama:

set odps.sql.type.system.odps2=true;
set odps.sql.session.resources=odps-test.jar;
set odps.sql.session.java.imports=com.aliyun.odps.test.*;
-- With the import set, you can omit the full package prefix.
select new IntegerMaxValue().evaluate();

odps.sql.session.java.imports bir sınıf yolu (örneğin, java.math.BigInteger) veya joker karakter (*) kabul eder. Statik içe aktarmalar desteklenmez.

Desteklenen işlemler

UDT'ler SQL ifadelerinde aşağıdaki işlemleri destekler:

  • new kullanarak nesne oluşturma — örnek: new java.math.BigInteger('123')

  • Başlatıcı listeleriyle new kullanarak dizi oluşturma — örnek: new Integer[] { 1, 2, 3 }

  • Örnek ve statik yöntemleri çağırma

  • Genel örnek ve statik alanlara erişme

Yalnızca genel yöntemlere ve genel alanlara erişilebilir. Tüm tanımlayıcılar (paket adları, sınıf adları, yöntem adları, alan adları) büyük/küçük harfe duyarlıdır. Anonim sınıflar ve lambda ifadeleri desteklenmez. Değer döndürmeyen işlevler ifadelerde çağrılamaz.

Veri türleri

Tür eşlemesi

Java veri türleri MaxCompute yerleşik türleriyle eşlenir. Java UDF'leri için kullanılan aynı eşleme UDT'ler için de geçerlidir.

  • Yerleşik tür yöntemlerini doğrudan çağırma: '123'.length(), 1L.hashCode()

  • Yerleşik işlevlerde UDT kullanma: chr(Long.valueOf('100')) — Long.valueOf java.lang.Long döndürür ve bu da yerleşik BIGINT türüne eşlenir

  • Java ilkel türleri otomatik olarak kutulama türlerine dönüştürülür

Yeni yerleşik veri türleri için sorguyu çalıştırmadan önce set odps.sql.type.system.odps2=true; ekleyin.

Tür dönüşümleri

  • SQL tür dönüşümleri desteklenir: cast(1 as java.lang.Object)

  • Java tarzı tür dönüşümleri desteklenmez: (Object)1

  • UDT nesneleri örtük olarak temel sınıf nesnelerine dönüştürülebilir

  • UDT nesneleri açıkça temel sınıf veya alt sınıf nesnelerine dönüştürülebilir (yayınlanabilir)

  • İlişkisiz iki tür arasında dönüşüm yapmak, yerleşik tür dönüşümüyle aynı kuralları izler. Örneğin, java.lang.Long türünü java.lang.Integer türüne dönüştürmek, BIGINT'i INT'e dönüştürmeyle aynı kuralları uygular ve bu durum veri kaybına neden olabilir.

UDT nesneleri diske kaydedilemez ve doğrudan tablolara eklenemez (DDL, UDT'leri sütun türü olarak desteklemez). UDT değeri yerleşik bir türe örtük olarak dönüştürülebiliyorsa tabloya yazılabilir. BINARY otomatik serileştirmeyi destekler — byte[] dizileri kaydedilebilir ve serileştirme kaldırılabilir. Bir UDT'yi kalıcı hale getirmek için serileştirme ve serileştirme kaldırma yöntemlerini kullanarak BINARY'ye dönüştürün. UDT değerleri doğrudan son çıktıda görünemez. Herhangi bir UDT'yi görüntüleme amacıyla toString() çağırarak java.lang.String türüne dönüştürün. Hata ayıklama sırasında tüm UDT çıktısını otomatik olarak dizelere dönüştürmek için şunu kullanın: Bu bayrak yalnızca PRINT ifadeleri için geçerlidir, INSERT ifadeleri için geçerli değildir.
set odps.sql.udt.display.tostring=true;

Generics (Jenerikler)

UDT'ler Java jeneriklerini destekler. Derleyici, tür parametresini bağımsız değişkenden çıkarır:

-- Returns java.util.List<java.math.BigInteger>
java.util.Arrays.asList(new java.math.BigInteger('1'))

Tür parametrelerini oluşturucu çağrılarında açıkça belirtin veya java.lang.Object kullanın:

-- ArrayList<Object>
new java.util.ArrayList(java.util.Arrays.asList('1', '2'))

-- ArrayList<String>
new java.util.ArrayList<String>(java.util.Arrays.asList('1', '2'))

Operatör anlambilimi

Tüm operatörler Java anlambilimini değil, MaxCompute SQL anlambilimini izler:

  • Dize birleştirme: String.valueOf(1) + String.valueOf(2) ifadesi 3 döndürür (her iki dize örtük olarak DOUBLE'a yayılanır ve toplanır). Dizeleri birleştirmek için bunun yerine bir dize birleştirme işlevi kullanın.

  • Eşitlik: = operatörü bir SQL karşılaştırma operatörüdür, Java referans eşitliği değildir. İki nesnenin eşdeğer olup olmadığını kontrol etmek için equals yöntemini kullanın.

Nesne eşitliği ve veri karıştırma

UDT'lerin nesne eşitliği konusunda net bir tanımı yoktur. Veri karıştırma sırasında nesneler süreçler ve fiziksel makineler arasında iletilebilir, bu da tek bir nesnenin iki farklı başvuru olarak görünmesine neden olabilir. UDT nesnelerini karşılaştırmak için = yerine her zaman equals yöntemini kullanın.

Aynı satır veya sütun içindeki nesneler ilişkilidir, ancak satırlar veya sütunlar arasındaki ilişki garanti edilmez.

Sınırlamalar

UDT'ler JOIN, GROUP BY, DISTRIBUTE BY, SORT BY, ORDER BY veya CLUSTER BY yan tümcelerinde karıştırma anahtarı olarak kullanılamaz. UDT'ler bu aşamalardaki ifadelerde geçerlidir ancak çıktı olamazlar. Örneğin:

  • group by new java.math.BigInteger('123') — desteklenmez

  • group by new java.math.BigInteger('123').hashCode() — desteklenir, çünkü hashCode() int.class döndürür ve bu da yerleşik INT türüne eşlenir

UDF'ler, kullanıcı tanımlı toplama işlevleri (UDAF) ve UDT'ler aşağıdaki tablo türlerinden veri okuyamaz:

  • Şema evriminin uygulandığı tablolar

  • Karmaşık veri türleri içeren tablolar

  • JSON veri türleri içeren tablolar

  • İşlemsel tablolar

Kaynaklara erişme

MaxCompute SQL'de, ExecutionContext nesnesini almak için com.aliyun.odps.udf.impl.UDTExecutionContext.get() statik yöntemini çağırın. Kaynak olarak kaydedilen dosyalar ve tablolar dahil olmak üzere mevcut yürütme bağlamına erişmek için bu nesneyi kullanın.

Performans hususları

UDT performansı UDF performansına benzer. Optimize edilmiş hesaplama motoru belirli senaryolarda ek iyileştirmeler sağlar:

  • Yerel işlemler için serileştirme ek yükü yok. Bir UDT nesnesi aynı süreç içinde kullanıldığında (JOIN veya AGGREGATE aşamalarında olduğu gibi veri karıştırma gerekmediğinde) serileştirme ve serileştirme kaldırma atlanır.

  • Kod üretime dayalı çalışma zamanı. UDT'ler yansıma yerine Kod Üretimi aracılığıyla çalışır, bu nedenle yansıma ek yükü yoktur. Birden fazla UDT çağrısı tek bir işlev çağrısında gruplanır — örneğin, values[x].add(values[y]).divide(java.math.BigInteger.valueOf(2)) bir kez çağrılır ve çağrı başına arayüz ek yükünden kaçınılır.

Güvenlik

UDT'ler, UDF'lerle aynı Java korumalı alanı modeline tabidir. Korumalı alan tarafından kısıtlanan işlemleri gerçekleştirmek için bu işlemlerin korumalı alan izolasyonunu iptal edin veya korumalı alan izin listesine katılmak için başvurun.

Geliştirilecek özellikler

Aşağıdaki özellikler gelecek sürümler için planlanmaktadır:

  • Değer döndürmeyen işlevleri ve doğrudan aktarılan verileri kullanan işlevleri (dönüş değeri yoksayıldığı için List arabiriminin add yöntemi gibi) çağırma.

  • Anonim sınıfları ve lambda ifadelerini kullanma.

  • UDT'leri karıştırma anahtarı olarak kullanma.

  • Python gibi daha fazla programlama dilini destekleme.

Sonraki adımlar