CHashtag

[C#] Guid 사용방법 (생성, 비교, ToString()) 본문

C#

[C#] Guid 사용방법 (생성, 비교, ToString())

HyoSeong 2022. 4. 5. 22:53
반응형

안녕하세요.

 

오늘은 Guid에 대해 알아보고자 합니다.

 

Guid 란


Guid는 Globally Unique Identifier의 약자로, 전역 고유 식별자라는 의미를 가지는 식별자입니다.

 

세상에는 여러 가지 식별자가 존재합니다.

Uuid, NanoId, Cuid, 그리고 Git에서 사용하는 Hash 등 이 있죠.

 

기본적으로 식별자는 값(객체)를 식별하기 위한 요소로, Mysql의 PK와 같이 고유하여야 합니다.

 

그렇다면 위에서 나열한 식별자들은 자체적으로 중복되지 않는 로직이 존재하는 것일까요?

 

정답은 아닙니다.

단지 나올수 있는 값이 매~~~ 우 많아서, 절대 겹치지 않을 것이다.라는 가정을 하는 것입니다.

 

Uuid를 예로들면 실제로 생성 가능한 식별자의 개수는 10의 38 제곱, 340간 개나 됩니다.

엄청나죠? ㅎㅎ

 

Guid vs Uuid

Guid와 Uuid는 기본적으로 굉장히 비슷하게 생겼고, 특징도 거의 같습니다.

 

8-4-4-4-12 의 format이다.

대소문자를 구분하지 않는다. (Guid의 경우 대문자로만 사용할 것을 권장함)

format한 자릿수가 16진수이다. (0~F 중 하나의 값을 가진다.)

 

이와 관련된 상세 내용은 아래 링크를 참고해주시면 되겠습니다.

상세한 내용이 적혀있어 아주 재미있는 토론입니다.

https://stackoverflow.com/questions/246930/is-there-any-difference-between-a-guid-and-a-uuid

 

Is there any difference between a GUID and a UUID?

I see these two acronyms being thrown around and I was wondering if there are any differences between a GUID and a UUID?

stackoverflow.com

 

Guid는 16진수를 사용하지만 DB에 Text로 저장하는 이유는?

Guid는 기본적으로 문자 하나당 16진수 즉 4bit입니다.

그래서 가장 효율적으로 데이터를 저장한다면 16byte면 충분하다는 뜻이죠.

 

하지만 왜 EF에서 Guid를 생성한 뒤 Code-First Migration을 진행하면 CHAR(36)으로 저장하는 것일까요?

CHAR(36)은 무려 36byte입니다. (여기서는 - 가 포함 되기 때문에 더 커지는 것입니다.)

 

왜 EF에서는 이렇게 비효율적인 방법을 사용하는 것일까요?

 

찾아보니 최신버전 EF에서는 binary16으로 저장한다고 합니다. ㅎㅎ

제가 레거시 버전을 사용 중이어서 그런 것 같네요 ㅠ

https://stackoverflow.com/questions/45120152/guid-property-on-mysql-entity-framework

 

Guid property on Mysql Entity Framework

I'm using Entity Framework with MySql extension on ASP.NET Core application. One of my domain model Message have Guid property and when I want to execute any operation on my DbContext I'm receiving...

stackoverflow.com

 

사용방법


이제 C#에서 Guid를 사용하는 방법에 대하여 간단한 예문과 함께 알아보도록 하겠습니다.

 

새로운 Guid 발급

Guid guid = new Guid();

위와같이 Guid를 생성하게 되면 값이 모두 0으로 들어있게 됩니다.

그래서 아래처럼 사용하셔야 합니다.

Guid guid = Guid.NewGuid();

하지만 모든 Model에 Guid를 생성하는 것은 귀찮은 일입니다.

 

Guid Null 확인

Guid는 기본적으로 non-nullable value입니다.

하지만 if문에서 null과 비교는 가능합니다.

 

그렇기에 많은 사람들이 아래와 같은 코드를 작성하곤 합니다.

Guid guid;

if(guid == null)
{
    Guid guid = Guid.NewGuid();
}

하지만 이런 로직을 구현하였다면 if문안에 들어갈 일은 절대 없을 것입니다.

 

그렇기 때문에 아래와 같이 구현하셔야 합니다.

Guid guid;

if(guid == default(Guid))
{
    Guid guid = Guid.NewGuid();
}

default(Guid)는 기본적으로 [00000000-0000-0000-0000-000000000000]을 가지기 때문에 값이 비어있는지 확인할 수 있는 것입니다.

 

String ➡ Guid

위에서 Guid는 기본적으로 대문자로 사용할 것을 권장하지만, 대소문자를 구분하지 않도록 구현되어 있습니다.

그렇기 때문에 대소문자는 신경 쓰지 않으셔도 괜찮고, format과 16비트만 잘 확인해주시면 됩니다.

string guidStr = "d85b1407-351d-4694-9392-03acc5870eb1";
bool canParse = Guid.TryParse(guidStr, out Guid guid);

if(canParse)
{
    // ..
}

 

Guid ➡ String

Guid guid = Guid.NewGuid();

string guidStr = guid.ToString();

 

응용

Guid 생성과 Guid Null 비교를 잘 응용하면 데이터 모델에서 자동으로 Guid를 생성해주는 로직을 구현할 수 있습니다.

아래와 같이 말이죠. Singleton 패턴과 비슷하죠? ㅎㅎ

public class DataModel1
{
    private Guid _guid;
    public Guid Guid
    {
        get
        {
            if (_guid == default(Guid))
            {
                _guid = Guid.NewGuid();
            }

            return _guid;
        }
        set
        {
            _guid = value;
        }
    }
}

 

 

위 내용에서 다루지 못한 부분은 댓글 달아주시거나, 아래 링크 확인하시면 정말 자세하게 확인하실 수 있으니 참고 부탁드립니다.

https://github.dev/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Guid.cs

 

 

긴 글 읽어주셔서 감사합니다.

 

도움이 되었길 바랍니다.

반응형