맥어드레스 정렬관련 sql 질문드립니다

안녕하세요?

저로써는 조금 난감한 문제가 발생하여 질문드리게 되었습니다.

mac어드레스를 관리하는 테이블이 있습니다.

예를들어서
mac
50:00:FF:FF:FF:00 부터 순차적으로 증가하여 약 5000만개정도의 데이터가 있는데요…

이 맥어드레스 컬럼이 varchar로 되어있습니다.
ex) 5000FFFFFF00 형식으로요…

서버데이터가 날아가버린 상태로… 가장 최종 백업본이 올해 1월입니다.

seq 컬럼도 없는 상황이구요…맥 어드레스 컬럼과 사용 유무 컬럼이 있습니다…

다행히 마지막 사용한 mac어드레스 값을 알고 있는 상황입니다.

그냥 간랸히 5001000000 이라고 가정했을때 해당 맥보다 낮은 것에 대해

사용컬럼을 전부 y로 바꿔줘야 할것같은데…

문제는 이게 hex데이터긴 하지만 string 형식이라서 정렬도 되지 않습니다.(부족한 제 기준…)

제가 말주변이 없어 이게 그리 어려운 상황은 아닌데 설명을 잘 하지 못하며 질문드리는것 같아 죄송합니다.

무작정 5000만개의 데이터를 전부 가져와서 하나씩 일일히 변환해가며 순차적으로 증가하며 사용컬럼을 y로 바꾸는 무식한 짓은 하고 싶지 않습니다. 서버도 박살나버릴것같은 불길한 예감도 들고…

어떤 좋은 방법이 없을까요?ㅠㅠ

1개의 좋아요

질문이 정리가 필요할것 같습니다.
데이타 record 갯수 5천만개
데이타형식 varchar

데이타 예시 0x:102:xx…

지금 현재 데이타는 단순 text
02:xxx:21121
02:xxx:21122
02:xxx:21121

뭐이런식 인가요??

이걸 다시 db에 부으신다는 얘기신가요??
db에 붓는데 왜 ?? 정렬이 필요하신지??
아 다시보니 가지고있는 원시 데이타 hex 라는 얘기신가요?
이걸 varchar 형식의 테이블로 넣는다는 얘기신가요??
그리고 그 table은

seq | macaddr | useyn
1 01:11 Y
이런식으로 넣어야 된다는 얘기신가요??

만약 그렇다면 Hex 를 순차적으로 읽으면서 십만개정도 분할해
bulk copy 하시면 1~2시간이면 될수도 있고
아니면 csv 같은것으로 변환해서 넣을수도 있는데
데이타가 너무 크네요 이걸 text 로 여려개로 쪼개는 작업부터 해야할것 같습니다.

데이타 오천만개는 좀 다루기 힘든 큰 데이타이긴 합니다.

1개의 좋아요

블루투스 모듈을 장착하는 모 제품을 생산하는 공장인데

맥이라는것이 사용할때마다 하나씩 데이터를 넣는것이 아니라.

사전에 약 5000만개정도를 미리 사두고
00:00:00:00:00 부터 뒤로 5000만개를 쓰겠다고
이미 데이터를
캡처

이런형식으로 때려박아놨습니다…(예시로 작성)

마지막 사용 맥값을 알고 있는데

seq 겪 컬럼이 없다보니

무작정 303F0000000F보다 작은 모든 필드의 사용 유무 상태를 1로 바꿀 방법이 저로서는 도저히 떠오르지 않아서요…

진짜 저런 방법밖에 없을까요?

뭔가 쿼리로 쨘 하고 해결할수 있는방법이 없을까요 ㅋㅋㅋ

살려주세요 ㅠㅠ

1개의 좋아요

SQL Server에서 MAC address를 곧바로 대소 비교가 가능한 정수 타입으로 변환하는 함수는 없기 때문에, 아래와 같이 변환하는 함수 (!= 스토어드 프로시저)를 하나 만들고 시작해야 할 것 같아보이네요!

CREATE FUNCTION dbo.ConvertMacAddressToInteger (@macAddress NVARCHAR(17))
RETURNS BIGINT
AS
BEGIN
    DECLARE @hexString NVARCHAR(12)
    DECLARE @hexTable TABLE (HexValue CHAR(1), DecValue INT)

    -- HEX 값을 10진수로 변환하기 위한 테이블 생성
    INSERT INTO @hexTable (HexValue, DecValue)
    VALUES ('0', 0), ('1', 1), ('2', 2), ('3', 3), ('4', 4), ('5', 5),
           ('6', 6), ('7', 7), ('8', 8), ('9', 9), ('A', 10), ('B', 11),
           ('C', 12), ('D', 13), ('E', 14), ('F', 15)

    -- MAC 주소에서 콜론(:) 제거
    SET @macAddress = REPLACE(@macAddress, ':', '')

    -- MAC 주소의 앞 12자리를 HEX 값으로 추출
    SET @hexString = LEFT(@macAddress, 12)

    -- HEX 값을 10진수로 변환하여 계산
    DECLARE @result BIGINT = (
        SELECT SUM(DecValue * POWER(16, 11 - (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1)))
        FROM (
            SELECT SUBSTRING(@hexString, number, 1) AS HexChar
            FROM master.dbo.spt_values
            WHERE type = 'P' AND number BETWEEN 1 AND 12
        ) AS HexChars
        JOIN @hexTable AS HexValues ON HexChars.HexChar = HexValues.HexValue
    )

    RETURN @result
END

그리고 아래와 같이 쓸 수 있을 겁니다.

DECLARE @macAddress NVARCHAR(17)
SET @macAddress = '12:34:56:78:9A:BC'

SELECT dbo.ConvertMacAddressToInteger(@macAddress) AS MacAddressInteger

테스트를 해보셔야 겠지만, 303F0000000F 값을 정수값으로 만들어놓고, 대소 비교를 하면서 원하는 목적을 달성하실 수 있지 않을까 싶습니다.

참고로, 이 방법을 쓴다고 해도 SQL Server에 많은 부하를 주는건 피하기 어려울 것 같습니다. 라이브/프로덕션 데이터베이스에서 작업하기 부담스러우시다면, MDF/LDF 파일만 다른 곳으로 백업하셔서 분리된 인스턴스나 SQL Local DB 등에서 작업하시면 좀 더 안전할 것 같습니다.

혹시 더 좋은 방법/아이디어가 있을지도 모르겠네요!

6개의 좋아요

제가 잘모르는 분야라 밑에 @rkttu 님의 해결책 참고하시면서 하시면서 피드백 받으시면서 해결하시면 좋을것 같아요

3개의 좋아요

와… 정말 감사합니다… 내용은 아직 이해도 못한채로 너무 감사해서 댓글먼저 달았습니다.

정독하고 제안해주신 방법대로 진행하여 결과도 말씀드릴수 있도록 할게요 정말 감사합니다!

3개의 좋아요

아, 그리고 혹시 MAC 문자열 자체가 보관되어야 할 이유가 있는게 아니라면, 처음부터 정수값으로 보관을 해두도록 테이블을 고치는 것도 고려해보실 수 있을 것 같습니다. 데이터로서 MAC 주소 문자열 표현이 유효한 것이라면 재고해봐야겠지만, 그런게 아니라면 결국 비교를 위해서 MAC 주소를 저장하고 있어야 할테니 문자열로 저장했다가 정수로 변환하는 비효율보다는 처음부터 정수 값으로 저장을 해두었다가 필요할 때만 MAC 주소 표현으로 표현부에서 다루는 것이 더 효율적일 것 같다는 생각이 듭니다. :+1:

5개의 좋아요

제가 테이블 구조는 수정 할 수 없습니다… ㅠㅠ 저희것이 아니니까요…ㅠㅠ

이미 수없이 요청했지만 본인들은 꼭 그래야 만 하는 이유가 있다고 하니

저는 그냥 요청사항을 해낼뿐…입니다…ㅎㅎ

2개의 좋아요