جدول بحث قليلة الكثافة السكانية في SQL

StackOverflow https://stackoverflow.com/questions/649374

  •  19-08-2019
  •  | 
  •  

سؤال

وأنا أحاول أن أكتب طريقة البحث لتحديد رسالة SMS لإرسالها إلى المستخدم استنادا إلى عدد قليل من المعالم المرتبطة المستخدم / النظام. سيكون لدينا رسالة الافتراضية التي سيتم استخدامها كملاذ أخير، ولكن هناك عدة طرق لتجاوز الرسالة معايير مختلفة. هنا هو ما قلته حتى الآن للاستعلام بحث - هل هناك أي وسائل أفضل للقيام بذلك؟ ربما البحث ليس هو النهج الصحيح لهذا؟

وهنا جدول البحث:

MessageLookup
{
ID bigint PK                          
Key varchar                           
CampaignTypeID bigint FK,             
ServiceProviderID bigint FK nullable, -- optional override parameter
DistributorID bigint FK nullable,     -- optional override parameter
CampaignID bigint FK nullable,        -- optional override parameter
Message varchar                   
}

وهنا مثال على ما يمكن أن تبدو الجدول مثل:

   ID Key  CTID SPID DistID CampID Message
    1 Help 1    NULL NULL   NULL   'This is the default message'
    2 Help 1    375  NULL   NULL   'This is the SP375 message'
    3 Help 1    377  NULL   NULL   'This is the SP377 message'
    4 Help 1    NULL 13     NULL   'This is the Dist13 message'
    5 Help 1    375  13     NULL   'This is the SP375/Dist13 message'
    6 Help 1    NULL 13     500    'This is the Dist13/Camp500 message'
    7 Help 1    375  13     500    'This is the SP375/Dist13/Camp500 msg'
    8 Help 1    NULL NULL   500    'This is the Camp500 help message'

وهنا يتم الاستعلام لدي:

select
    --top 1
    *
from MessageLookup ml
where ml.[Key] = @Key
and ml.CampaignTypeID = @CampaignTypeID
and
(
    ml.ServiceProviderID = @ServiceProviderID or
    ml.ServiceProviderID is null
)
and
(
    ml.DistributorID = @DistributorID or
    ml.DistributorID is null
)
and
(
    ml.CampaignID = @CampaignID or
    ml.CampaignID is null
)
order by
    CampaignID desc, -- highest precedence lookup param
    DistributorID desc,
    ServiceProviderID desc -- lowest precedence lookup param
هل كانت مفيدة؟

المحلول

ولست متأكدا ما هو أفضل وسيلة، ولكن هنا بعض البدائل:

والفكر واحد سيكون لتخزين نمط مع كل قاعدة، كما يلي:

ID Key CTID Rule        Message
1 Help 1    '[%:%:%]'    'This is the default message'
2 Help 1    '[375:%:%]'  'This is the SP375 message'
3 Help 1    '[377:%:%]'  'This is the SP377 message'
4 Help 1    '[%:13:%]'   'This is the Dist13 message'
5 Help 1    '[375:13:%]' 'This is the SP375/Dist13 message'

ومن ثم استخدام اختبار LIKE بدل كل يستخدم المعامل.

وفكرة أخرى تتمثل في استخدام الخارجي تنضم.

وأو (اللعب خارج الجواب الذي جاء فقط في) لتجف الامور مزيدا من الكتابة:

where ml.[Key] = @Key
  and ml.CampaignTypeID = @CampaignTypeID
  and IsNull(ml.ServiceProviderID = @ServiceProviderID,true)
  and IsNull(ml.DistributorID     = @DistributorID,    true)
  and IsNull(ml.CampaignID        = @CampaignID,       true)

نصائح أخرى

وأعتقد أن هذا هو نهج صحيح، وسهلة لتمديد، القصد من ذلك هو واضح جدا، ويمكنك أن ترتب ومزود طريق القيام بما يلي

select
    --top 1
    *
from MessageLookup ml
where ml.[Key] = @Key
and ml.CampaignTypeID = @CampaignTypeID
and ml.ServiceProviderID = IsNull(@ServiceProviderID, ml.ServiceProviderID)
and ml.DistributorID = IsNull(@DistributorID, ml.DistributorID)
and ml.CampaignID = IsNull(@CampaignID, ml.CampaignID)
....

ما تقومون به من المنطقي، ويعمل. إذا كنت بعد أفضل الممارسات - لا تستخدم "SELECT *" - تعداد الأعمدة التي تقوم بتحديد

وأنا أعتقد أن تصميم قاعدة البيانات بطريقة مختلفة، مع طاولة واحدة TA التي من شأنها أن تكون (MSGID، مفتاح، CTID، رسالة) والسل واحد آخر من شأنه أن تخزين (MSGID، ID، IDTYPE) حيث ID سيمثل CampID / DistId / DefaultId (المشار إليها IDTYPE)، وPK من الذي ينبغي أن يكون (ID، IDTYPE، MSGID) في هذا النظام. يمكنك أن تخصص IDTYPE قيمة رقمية تشير إلى الأولوية، مع 0 لصالح الافتراضي (وID مطابقة 0). جميع الأعمدة NOT NULL.

إذا فهمت جيدا مشكلتك، ويتم الإدخال من ثلاث قيم x و y و z (بالإضافة إلى ضمني 0 في حالتي)، تريد العودة الرسالة التي لديك في معظم المباريات، و، في حالة المساواة والنظام من قبل IDTYPE.

select MSGID, count(*) as nbr_candidates, max(IDTYPE) as priority
from TB
where (ID = x and IDTYPE = ...)
   or (ID = y and IDTYPE = ...)
   or (ID = z and IDTYPE = ...)
   or (ID = 0 and IDTYPE = 0)
group by MSGID
order by 2 desc, 3 desc

ويجب أن تعود "أفضل رسالة" كأول خلافها، وكل ما تحتاج إلى إضافة هو

top 1

وثم الانضمام مع الجدول الآخر. هذا ومن المرجح أن يكون أسرع من حل طاولة واحدة، وذلك لأن الجدول TB يحتوي فقط على معرفات رقمية وسيكون مضغوط جدا، والانضمام سيكون حظة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top