웹사이트 검색

프로그래밍에서 임피던스 불일치란 무엇입니까?


프로그래밍 임피던스 불일치는 데이터를 다른 아키텍처 패러다임으로 변환해야 할 때 발생합니다. 가장 눈에 띄는 예는 객체 지향 코드베이스와 관계형 데이터베이스와 관련이 있습니다.

데이터베이스에서 데이터를 가져오거나 삽입할 때 임피던스 불일치가 발생합니다. 코드베이스 내의 개체 또는 클래스 속성은 해당 데이터베이스 테이블 필드에 매핑되어야 합니다.

매핑 및 관계

클래스가 반드시 개별 데이터베이스 테이블에 직접 매핑되는 것은 아닙니다. 개체를 구성하려면 여러 테이블의 데이터를 집계하여 사용해야 할 수 있습니다.

또한 데이터 간의 관계를 처리해야 합니다. 관계형 데이터베이스는 다른 레코드를 참조할 수 있도록 하여 이를 간단하게 만듭니다. JOIN을 사용하여 관계로 캡슐화된 모든 데이터에 액세스할 수 있습니다.

class="kw1">CREATE class="kw1">TABLE productTypesclass="br0">(
    ProductTypeUuid class="kw1">VARCHARclass="br0">(class="nu0">32class="br0">) class="kw1">PRIMARY class="kw1">KEYclass="sy0">,
    ProductTypeName class="kw1">VARCHARclass="br0">(class="nu0">255class="br0">) class="kw1">NOT class="kw1">NULL class="kw1">UNIQUE
class="br0">);
 
class="kw1">CREATE class="kw1">TABLE productsclass="br0">(
    ProductUuid class="kw1">VARCHARclass="br0">(class="nu0">32class="br0">) class="kw1">PRIMARY class="kw1">KEYclass="sy0">,
    ProductName class="kw1">VARCHARclass="br0">(class="nu0">255class="br0">) class="kw1">NOT class="kw1">NULL class="kw1">UNIQUEclass="sy0">,
    ProductType class="kw1">VARCHARclass="br0">(class="nu0">32class="br0">) class="kw1">NOT class="kw1">NULLclass="sy0">,
    class="kw1">FOREIGN class="kw1">KEY class="br0">(ProductTypeclass="br0">) class="kw1">REFERENCES productTypesclass="br0">(ProductTypeUuidclass="br0">) class="kw1">ON class="kw1">DELETE CASCADE
class="br0">);

일반 SQL을 사용하면 다음과 같은 간단한 쿼리를 통해 Product와 해당 ProductType의 결합된 속성을 가져올 수 있습니다.

class="kw1">SELECT class="sy0">* class="kw1">FROM products
class="kw1">INNER class="kw1">JOIN productTypes class="kw1">ON ProductTypeUuid class="sy0">= ProductType;

그런 다음 Product 및 해당 ProductType의 속성은 동일한 평면 구조에서 액세스됩니다.

class="kw1">echo class="re0">$recordclass="br0">[class="st0">"ProductName"class="br0">]class="sy0">;
class="kw1">echo class="re0">$recordclass="br0">[class="st0">"ProductTypeName"class="br0">]class="sy0">;

이 플랫 어레이는 복잡한 애플리케이션에서 빠르게 제한됩니다. 개발자는 자연스럽게 Product 및 ProductType 엔터티를 별도의 클래스로 모델링합니다. 그런 다음 Product 클래스는 ProductType의 인스턴스를 보유할 수 있습니다. 그 모습은 다음과 같습니다.

final class="kw2">class ProductType class="br0">{
 
    class="kw2">public class="kw2">function __constructclass="br0">(
        class="kw2">public string class="re0">$Uuidclass="sy0">,
        class="kw2">public string class="re0">$Nameclass="br0">) class="br0">{class="br0">}
 
class="br0">}
 
final class="kw2">class Product class="br0">{
 
    class="kw2">public class="kw2">function __constructclass="br0">(
        class="kw2">public string class="re0">$Uuidclass="sy0">,
        class="kw2">public string class="re0">$Nameclass="sy0">,
        class="kw2">public ProductType class="re0">$ProductTypeclass="br0">) class="br0">{class="br0">}
 
class="br0">}

이제 코드에 상당한 임피던스 불일치가 있습니다. 데이터베이스 쿼리의 레코드를 제품 인스턴스로 나타내려면 특정 형식의 특수 매핑이 필요합니다.

특정 유형의 모든 제품에 액세스하려는 경우 추가 문제가 발생합니다. 코드에서 이를 수행하는 방법은 다음과 같습니다.

final class="kw2">class ProductType class="br0">{
 
    class="kw2">public class="kw2">function __constructclass="br0">(
        class="kw2">public string class="re0">$Uuidclass="sy0">,
        class="kw2">public string class="re0">$Nameclass="sy0">,
        ProductCollection class="re0">$Productsclass="br0">) class="br0">{class="br0">}
 
class="br0">}

이제 ProductType은 궁극적으로 Product 인스턴스 배열을 포함하는 ProductCollection을 보유합니다. 이렇게 하면 양방향 관계 참조가 생성됩니다. ProductType에는 모든 제품이 포함되고 각 Product에는 해당 제품 유형이 포함됩니다.

이러한 형태의 모델링은 관계형 패러다임 내에 존재하지 않습니다. 각 형태의 연결은 단일 관계형 링크 레코드로 표시됩니다. 양방향 참조를 사용하면 개체 속성에 대한 개발자 액세스가 간소화됩니다. 그러나 데이터베이스와 주고받을 때 더 복잡한 매핑이 필요합니다. 이는 SQL이 기본적으로 모델의 의미를 이해하지 못하기 때문입니다.

계층 구조 고려

위에서 설명한 모델은 코드베이스에 계층 구조를 생성합니다. Product는 ProductType 아래에 있습니다. 이것은 논리적으로 들리며 실제 세계에 대한 우리의 기대와 일치합니다.

관계형 데이터베이스는 계층을 존중하지 않습니다. 모든 관계는 동일하므로 관계형 데이터베이스는 본질적으로 플랫 구조를 가집니다. 앞에서 JOIN으로 데이터를 가져올 때 이것을 보았습니다.

SQL에 계층 구조가 없다는 것은 모든 테이블이 서로 동등한 우선 순위를 갖는다는 것을 의미합니다. 이것의 효과는 논리적 개체 계층 구조에 깊이 중첩된 레코드의 속성에 쉽게 액세스할 수 있다는 것입니다. 또한 순환 종속성의 위험이 낮습니다.

위의 예는 Product와 ProductType이 코드에서 서로를 참조할 수 있음을 보여줍니다. 관계형 데이터베이스의 단순 특성으로 인해 이러한 특정 사례가 발생하지 않습니다. 순환은 여전히 일반 SQL에서 잘릴 수 있지만 객체 지향 코드로 모델링할 때보다 발생할 가능성이 적습니다.

객체 지향 프로그래밍은 단순한 객체를 보다 복잡한 객체로 구성하는 데 의존합니다. 관계형 모델에는 이러한 구성 또는 단순 및 복합 개념이 없습니다. 모든 레코드는 다른 레코드를 참조할 수 있습니다.

계승

또 다른 OOP 전용 기능은 상속입니다. 한 클래스가 다른 클래스를 확장하여 동작을 추가하는 것이 일반적입니다. 관계형 데이터베이스는 이를 복제할 수 없습니다. 테이블이 다른 테이블을 확장하는 것은 불가능합니다.

상속을 사용하는 코드베이스는 하위 개체가 관계형 데이터베이스를 통해 지속되거나 수화될 때 어려움에 직면하게 됩니다. 데이터베이스 내에서 일반적으로 두 개의 테이블이 필요합니다. 하나는 기본 개체(확장하려는)의 속성을 저장하고 다른 하나는 하위 개체의 속성을 처리합니다.

그런 다음 매핑 코드는 개체의 모든 속성을 반복합니다. 확장 클래스에서 파생된 속성이 첫 번째 코드에 삽입됩니다. 자식에 직접 정의된 항목은 두 번째 테이블에서 끝납니다.

데이터베이스에서 코드베이스로 다시 매핑할 때 유사한 시스템이 필요합니다. SQL JOIN은 하위 속성이 포함된 기본(확장) 클래스에 해당하는 모든 레코드를 가져오는 데 사용할 수 있습니다. 하위 속성이 포함된 레코드는 하위 클래스 인스턴스에 매핑됩니다.

class="kw1">CREATE class="kw1">TABLE parentclass="br0">(Id class="kw1">INTEGER class="kw1">PRIMARY class="kw1">KEYclass="sy0">, A class="kw1">INTEGERclass="br0">);
class="kw1">CREATE class="kw1">TABLE childclass="br0">(Id class="kw1">INTEGER class="kw1">PRIMARY class="kw1">KEYclass="sy0">, B class="kw1">INTEGERclass="sy0">, ParentId class="kw1">INTEGERclass="br0">);
class="kw2">class Parent class="br0">{
    class="kw2">public class="kw2">function __constructclass="br0">(int class="re0">$Aclass="br0">) class="br0">{class="br0">}
class="br0">}
 
final class="kw2">class Child class="kw2">extends Parent class="br0">{
    class="kw2">public class="kw2">function __constructclass="br0">(int class="re0">$Aclass="sy0">, int class="re0">$Bclass="br0">) class="br0">{class="br0">}
class="br0">}
 
class="co1">// Get records
class="co1">// SELECT * FROM parent INNER JOIN child ON child.ParentId = parent.Id;
class="re0">$objs class="sy0">= class="br0">[class="br0">]class="sy0">;
class="kw1">foreach class="br0">(class="re0">$records class="kw1">as class="re0">$recordclass="br0">) class="br0">{
    class="kw1">if class="br0">(class="kw3">issetclass="br0">(class="re0">$recordclass="br0">[class="st0">"B"class="br0">]class="br0">)class="br0">) class="br0">{
        class="re0">$objsclass="br0">[class="br0">] class="sy0">= class="kw2">new Childclass="br0">(class="re0">$recordclass="br0">[class="st0">"A"class="br0">]class="sy0">, class="re0">$recordclass="br0">[class="st0">"B"class="br0">]class="br0">)class="sy0">;
    class="br0">}
    class="kw1">else class="re0">$objsclass="br0">[class="br0">] class="sy0">= class="kw2">new Parentclass="br0">(class="re0">$recordclass="br0">[class="st0">"A"class="br0">]class="br0">)class="sy0">;
class="br0">}

상속을 도입하려면 더 복잡한 매핑 논리를 사용해야 합니다. 관계형 데이터베이스가 객체 지향 언어의 상속 기능을 모델링할 수 없기 때문에 이러한 임피던스 불일치가 발생합니다.

가시성 및 캡슐화

객체 지향 프로그래밍의 기본 원칙은 가시성과 캡슐화입니다. 속성은 public 또는 private로 선언됩니다. 객체의 내부 표현은 소비자를 위해 데이터를 미리 포맷하는 인터페이스 뒤에 숨길 수 있습니다.

관계형 데이터베이스에는 이러한 컨트롤이 없습니다. 필드를 private로 선언할 방법이 없으며 그렇게 해야 할 분명한 필요성도 없습니다. 데이터베이스에 저장된 각 데이터 조각에는 고유한 용도가 있습니다. 중복이 없어야 합니다.

이것은 객체 지향 패러다임으로 바뀔 때 반드시 사실이 아닙니다. 개체는 계산된 새로운 정보를 노출하기 위해 총 두 개의 데이터베이스 필드를 사용할 수 있습니다. 두 개별 필드의 값은 응용 프로그램과 관련이 없으므로 결과적으로 보기에서 숨겨질 수 있습니다.

class="kw1">CREATE class="kw1">TABLE productsclass="br0">(Price class="kw1">INTEGERclass="sy0">, TaxRate class="kw1">INTEGERclass="br0">);
final class="kw2">class Product class="br0">{
 
    class="kw2">public class="kw2">function __constructclass="br0">(
        class="kw2">protected int class="re0">$Priceclass="sy0">,
        class="kw2">protected int class="re0">$TaxRateclass="br0">) class="br0">{class="br0">}
 
    class="kw2">public class="kw2">function getTotalPriceclass="br0">(class="br0">) class="sy0">: int class="br0">{
        class="kw1">return class="br0">(class="re0">$this class="sy0">-> class="me1">Price class="sy0">* class="br0">(class="re0">$this class="sy0">-> class="me1">TaxRate class="sy0">/ class="nu0">100class="br0">)class="br0">)class="sy0">;
    class="br0">}
class="br0">}

애플리케이션은 세금을 포함한 총 제품 가격에만 관심이 있습니다. 단가와 세율은 제품 클래스에 의해 캡슐화됩니다. 가시성 컨트롤(보호됨)은 값을 숨깁니다. 공용 인터페이스는 두 필드를 사용하여 새 값을 계산하는 단일 메서드로 구성됩니다.

보다 일반적으로 객체 지향 프로그래밍은 인터페이스 프로그래밍을 옹호합니다. 속성에 대한 직접 액세스는 권장되지 않습니다. 인터페이스를 구현하는 클래스 메서드를 사용하면 나중에 대체 구현을 구성할 수 있습니다.

관계형 세계에는 이에 대한 직접적인 대응물이 없습니다. 데이터베이스 보기는 테이블과 추상 필드를 새로운 형식으로 결합하는 방법을 제공합니다. 그래도 여전히 필드 값으로 직접 작업하고 있습니다.

요약

개체 관계형 임피던스 불일치는 개체 지향 코드베이스가 관계형 데이터베이스와 데이터를 교환할 때 발생합니다. 데이터가 모델링되는 방식에는 근본적인 차이가 있습니다. 이것은 형식 간에 데이터를 바꾸는 매핑 계층의 도입을 필요로 합니다.

임피던스 불일치 문제는 객체 지향 언어 내에서 ORM을 채택하는 주요 동기 요인 중 하나입니다. 이를 통해 관계형 데이터 소스에서 복잡한 코드베이스 개체를 자동으로 수화할 수 있습니다. 전용 데이터 매핑 레이어가 없으면 가장 간단한 애플리케이션만 관계형 데이터베이스에 대한 간단한 경로를 갖게 됩니다.

관련기사:


판권 소유. © Linux-Console.net • 2019-2026