База данных: как мне отсортировать GUID? - PullRequest
4 голосов
/ 19 октября 2011

Мой первичный ключ использует guid.

Как мне отсортировать GUID?

Как насчет того, чтобы создать столбец datetime и записать штамп datetime, я мог бы затем отсортировать по datetime?это лучший способ сделать это?или есть лучшие способы?

Ответы [ 5 ]

2 голосов
/ 10 октября 2015
SELECT * 
FROM myTable
ORDER BY CAST(myGuid AS VARCHAR(36))
1 голос
/ 19 октября 2011

Guid - это то, что подразумевает название, уникальный идентификатор. Идентичность не подразумевает порядок, она просто дает вам возможность определить, должны ли две вещи быть идентичными. Для того, чтобы сортировать, вам нужно определить, что значит быть большим или менее значительным, чем что-либо еще. Из вашего вопроса кажется, что сортировка должна основываться на времени создания; Гиды не помогут вам в этом.

0 голосов
/ 15 марта 2018

Necromancing.GUID - это просто случайные числа, в них нет последовательности (если вы не используете sequentialuid - но он перезагружается после перезагрузки компьютера, так что это почти бессмысленно).Вот как на самом деле сортируются GUID:Код говорит сам за себя, магические части:

System.Guid g
g.ToByteArray();
int[] m_byteOrder = new int[16] // 16 Bytes = 128 Bit 
    {10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3};


public int Compare(Guid x, Guid y)
{
    byte byte1, byte2;

    //Swap to the correct order to be compared
    for (int i = 0; i < NUM_BYTES_IN_GUID; i++)
    {
        byte1 = x.ToByteArray()[m_byteOrder[i]];
        byte2 = y.ToByteArray()[m_byteOrder[i]];
        if (byte1 != byte2)
            return (byte1 < byte2) ? (int)EComparison.LT : (int)EComparison.GT;
    } // Next i 

    return (int)EComparison.EQ;
}

Полный код:

namespace BlueMine.Data
{


    public class SqlGuid
        : System.IComparable
        , System.IComparable<SqlGuid>
        , System.Collections.Generic.IComparer<SqlGuid>
        , System.IEquatable<SqlGuid>
    {
        private const int NUM_BYTES_IN_GUID = 16;

        // Comparison orders.
        private static readonly int[] m_byteOrder = new int[16] // 16 Bytes = 128 Bit 
        {10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3};

        private byte[] m_bytes; // the SqlGuid is null if m_value is null


        public SqlGuid(byte[] guidBytes)
        {
            if (guidBytes == null || guidBytes.Length != NUM_BYTES_IN_GUID)
                throw new System.ArgumentException("Invalid array size");

            m_bytes = new byte[NUM_BYTES_IN_GUID];
            guidBytes.CopyTo(m_bytes, 0);
        }


        public SqlGuid(System.Guid g)
        {
            m_bytes = g.ToByteArray();
        }


        public byte[] ToByteArray()
        {
            byte[] ret = new byte[NUM_BYTES_IN_GUID];
            m_bytes.CopyTo(ret, 0);
            return ret;
        }

        int CompareTo(object obj)
        {
            if (obj == null)
                return 1; // https://msdn.microsoft.com/en-us/library/system.icomparable.compareto(v=vs.110).aspx

            System.Type t = obj.GetType();

            if (object.ReferenceEquals(t, typeof(System.DBNull)))
                return 1;

            if (object.ReferenceEquals(t, typeof(SqlGuid)))
            {
                SqlGuid ui = (SqlGuid)obj;
                return this.Compare(this, ui);
            } // End if (object.ReferenceEquals(t, typeof(UInt128)))

            return 1;
        } // End Function CompareTo(object obj)


        int System.IComparable.CompareTo(object obj)
        {
            return this.CompareTo(obj);
        }


        int CompareTo(SqlGuid other)
        {
            return this.Compare(this, other);
        }


        int System.IComparable<SqlGuid>.CompareTo(SqlGuid other)
        {
            return this.Compare(this, other);
        }


        enum EComparison : int
        {
            LT = -1, // itemA precedes itemB in the sort order.
            EQ = 0, // itemA occurs in the same position as itemB in the sort order.
            GT = 1 // itemA follows itemB in the sort order.
        }


        public int Compare(SqlGuid x, SqlGuid y)
        {
            byte byte1, byte2;

            //Swap to the correct order to be compared
            for (int i = 0; i < NUM_BYTES_IN_GUID; i++)
            {
                byte1 = x.m_bytes[m_byteOrder[i]];
                byte2 = y.m_bytes[m_byteOrder[i]];
                if (byte1 != byte2)
                    return (byte1 < byte2) ? (int)EComparison.LT : (int)EComparison.GT;
            } // Next i 

            return (int)EComparison.EQ;
        }


        int System.Collections.Generic.IComparer<SqlGuid>.Compare(SqlGuid x, SqlGuid y)
        {
            return this.Compare(x, y);
        }


        public bool Equals(SqlGuid other)
        {
            return Compare(this, other) == 0;
        }


        bool System.IEquatable<SqlGuid>.Equals(SqlGuid other)
        {
            return this.Equals(other);
        }


    }


}
0 голосов
/ 19 октября 2011

Что вы пытаетесь сделать? сортировать по дате вставки? для этого вам действительно нужно поле datetime (или один из его вариантов), так как и направляющие, и ключи auto incr никогда не могут гарантировать порядок, только уникальность

Прочтите это для получения дополнительной информации: Сортировка первичного ключа

0 голосов
/ 19 октября 2011

Я бы пошел с колонкой int (или bigint), настроенной как личность. Каждый раз, когда вставляется строка, идентичность будет увеличиваться. Вы можете отсортировать этот столбец, чтобы получить строки в том порядке, в котором они были вставлены.

...