복붙노트

[PYTHON] Django의 기본 키를 해당 테이블에 대해 다른 정수로 대체하는 방법

PYTHON

Django의 기본 키를 해당 테이블에 대해 다른 정수로 대체하는 방법

기본 자동 증가 기본 양수 정수를 사용하는 장고 웹 응용 프로그램이 있습니다. 이 키는 응용 프로그램 전체에서 사용되며 자주 URL에 삽입됩니다. 이 숫자를 일반인에게 공개하고 싶지 않아서 데이터베이스에있는 사용자 또는 다른 항목의 수를 추측 할 수 있습니다.

이것은 빈번한 요구 사항이며 비슷한 질문에 답을 보았습니다. 대부분의 솔루션에서는 원래의 기본 키 값을 해싱하는 것이 좋습니다. 그러나 그 답 중 어느 것도 나의 필요를 정확하게 맞추지 못했습니다. 이들은 나의 요구 사항이다 :

이것을 달성하는 가장 좋은 방법은 무엇입니까? 다음과 같이 작동합니까?

def hash_function(int):
    return fancy-hash-function # What function should I use??


def obfuscate_pk(sender, instance, created, **kwargs):
    if created:
        logger.info("MyClass #%s, created with created=%s: %s" % (instance.pk, created, instance))
        instance.pk = hash_function(instance.pk)
        instance.save()
        logger.info("\tNew Pk=%s" % instance.pk)

class MyClass(models.Model):
    blahblah = models.CharField(max_length=50, null=False, blank=False,)


post_save.connect(obfuscate_pk, sender=MyClass)

해결법

  1. ==============================

    1.Instragam에서 사용하는 것과 동일한 접근 방식을 추천합니다. 그들의 요구 사항은 귀하의 요구 사항을 따르는 것처럼 보입니다.

    Instragam에서 사용하는 것과 동일한 접근 방식을 추천합니다. 그들의 요구 사항은 귀하의 요구 사항을 따르는 것처럼 보입니다.

    그들은 타임 스탬프, 데이터베이스 샤드 및 자동 증분 부분을 기준으로하여 41 비트를 갖는 시스템을 고안했습니다. 샤드를 사용하지 않는 것 같습니다. 당신은 시간 기반의 copmonent에 대해 41 비트를 가질 수 있고 무작위로 선택된 23 비트를 가질 수 있습니다. 동시에 레코드를 삽입 할 경우 충돌이 발생할 확률은 1 천 830 만분의 1입니다. 그러나 실제로는이 사실을 결코 알지 못합니다. 그렇다면 일부 코드는 어떻습니까?

    START_TIME = a constant that represents a unix timestamp
    
    def make_id():
        '''
        inspired by http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram
            '''
    
        t = int(time.time()*1000) - START_TIME
        u = random.SystemRandom().getrandbits(23)
        id = (t << 23 ) | u
    
        return id
    
    
    def reverse_id(id):
        t  = id >> 23
        return t + START_TIME 
    

    위 코드의 START_TIME은 임의의 시작 시간입니다. time.time () * 1000을 사용하여 값을 가져 와서 START_TIME으로 설정할 수 있습니다.

    내가 게시 한 reverse_id 메소드를 사용하면 레코드가 생성 된 시간을 알 수 있습니다. 해당 정보를 추적해야하는 경우 다른 정보를 추가하지 않고도 정보를 추적 할 수 있습니다! 따라서 기본 키는 실제로 저장소를 늘리는 것이 아니라 저장하는 것입니다.

    이제 이것이 당신의 모델이 될 것입니다.

    class MyClass(models.Model):
       id = models.BigIntegerField(default = fields.make_id, primary_key=True)  
    

    django 밖에서 데이터베이스를 변경하는 경우 make_id와 동일한 기능을 sql 함수로 만들어야합니다

    발 참고 사항. 이것은 Mongodb이 각 객체에 대해 _ID를 생성하는 데 사용한 접근법과 다소 비슷합니다.

  2. ==============================

    2.두 가지 우려 사항을 구분해야합니다.

    두 가지 우려 사항을 구분해야합니다.

    모델에 새 UUID 필드를 추가하고 개체 조회를 위해 PK 대신 뷰를 다시 매핑하는 것이 좋습니다.

  3. ==============================

    3.정말 간단한 해결책은 단순히 ID를 외부 소스로 보내기 전에 암호화하는 것입니다. 다시 암호 해독 할 수 있습니다.

    정말 간단한 해결책은 단순히 ID를 외부 소스로 보내기 전에 암호화하는 것입니다. 다시 암호 해독 할 수 있습니다.

  4. ==============================

    4.AUTO_INCREMENT를 유지하고 반 비밀 방식으로 전달하십시오 : 쿠키에서. 쿠키를 만들고, 설정하고, 읽는 데 약간의 코딩이 필요합니다. 그러나 쿠키는 진지한 해커를 제외한 모든 사람들에게 숨겨져 있습니다.

    AUTO_INCREMENT를 유지하고 반 비밀 방식으로 전달하십시오 : 쿠키에서. 쿠키를 만들고, 설정하고, 읽는 데 약간의 코딩이 필요합니다. 그러나 쿠키는 진지한 해커를 제외한 모든 사람들에게 숨겨져 있습니다.

  5. from https://stackoverflow.com/questions/37558821/how-to-replace-djangos-primary-key-with-a-different-integer-that-is-unique-for by cc-by-sa and MIT license