2013-07-22 20 views
8

मैं अपने डेटाबेस Laravel 4. का उपयोग कर के लिए एक उपयोगकर्ता आईपी पते को बचाने के लिए कोशिश कर रहा हूँ मॉडल करने के लिए मैं निम्नलिखित समारोह जो एक स्ट्रिंगlaravel 4 बचत आईपी पते

Request::getClientIp() 

मैं कैसे में संग्रहीत कर होगा रिटर्न मिला मेरा मॉडल? बस एक स्ट्रिंग या एक और अधिक कुशल तरीका है?

$table->string('ip_address'); 
+0

इस पर एक नजर डालें प्रासंगिक प्रश्न: http://stackoverflow.com/questions/6427786/ip-address-storing-in-mysql-डेटा – euantorano

+0

धन्यवाद! मैं वर्बिनरी पर विचार कर रहा था लेकिन मुझे इस प्रकार को स्कीमा बिल्डर में नहीं मिला है, क्या यह $ table-> बाइनरी ('डेटा') जैसा ही है; ? http://four.laravel.com/docs/schema – user391986

+0

ऐसा लगता है कि यह VARBINARY के बजाय बस एक बाइनरी कॉलम है: http://laravel.com/api/source-class-Illuminate.Database.Schema.Blueprint.html#576 -585 - इसका परीक्षण करने और हालांकि देखने के लिए एक अच्छा विचार हो सकता है। – euantorano

उत्तर

1
$table->string('ip_address', 39); 

क्योंकि एक IPv6 पता की अधिकतम लंबाई है 39.

आईपीवी 4 समर्थन किया जाएगा के रूप में यह लंबाई 15.

36

विकल्प 1 से अधिक नहीं करता है: VARCHAR उपयोग (45) कॉलम

किसी अन्य SO प्रश्न Maximum length of the textual representation of an IPv6 address?, में चर्चा को ध्यान में रखते हुए अधिकतम आईपीवी 4 सुरंग सुविधा सहित आईपीवी 6 की लंबाई लंबाई 45 है।

इस प्रकार, एक सुरक्षित प्रवास कमांड यह होगी:

$table->string('ip_address', 45); 

सकारात्मक:

  1. स्तंभ मानव पठनीय है। मान सेट करते समय रूपांतरणों की आवश्यकता नहीं है या देखने के लिए पंक्ति से पूछताछ की आवश्यकता नहीं है।

विपक्ष:

  1. यह विकल्प 2 की तुलना में अधिक स्थान का उपयोग करता है, लगभग 3 बार वास्तव में बड़ा है। लेकिन जब तक आप योजना बना रहे हैं तो लाखों पंक्तियों तक मैं ज्यादा चिंता नहीं करता।

विकल्प 2: उपयोग ब्लॉब स्तंभ

रूप @euantorano IP address storing in mysql database के लिए लिंक प्रदान की है, तो आप कुछ स्थान बचाने के लिए बाइनरी के रूप में आईपी संग्रहीत कर सकते हैं।

सरल जवाब उपयोग करने के लिए होगा:

$table->binary('ip_address'); 

सकारात्मक:

  1. बाइनरी में स्टोर IP पते आप कुछ जगह की बचत होगी।

विपक्ष:

  1. आप PHP के inet_pton() की तरह कुछ का उपयोग कर पहली बाइनरी आईपी पते स्ट्रिंग परिवर्तित करने के लिए की आवश्यकता होगी। कॉलम सीधे पठनीय नहीं होगा क्योंकि यह बाइनरी प्रारूप में संग्रहीत है। यदि आप इसे सीधे पूछने की कोशिश करते हैं तो आपको अजीब अक्षर या खाली दिखाई देंगे।आप नीचे विकल्प 3 में आईपी पते को स्टोर और पुनर्प्राप्त करने के अपने तरीके को देखना चाह सकते हैं।

  2. बार्लाइन नामक विधि के बावजूद लार्वेल में क्वेरी बिल्डर, वास्तव में आपके लिए create a BLOB column होगा। BLOB is stored off the table, out of the row buffer, जो संभवतः का मतलब है कम प्रदर्शन। और वास्तव में कोई कारण नहीं है कि बिनरी कॉलम प्रकार का उपयोग न करें क्योंकि हम जानते हैं कि आईपी पते बीएलओबी के लिए आवश्यक नहीं हैं।


विकल्प 3: का प्रयोग करें VARBINARY (16) स्तंभ

Laravel की क्वेरी बिल्डर आप MySQL का उपयोग कर रहे हैं, तो विकल्प 2 में उदाहरण के लिए एक ब्लॉब स्तंभ पैदा करता है, आप उपयोग करना चाहते जाएगा बेहतर प्रदर्शन के लिए बीएलओबी के बजाय वर्जीनिया (16)।

प्रवासन स्क्रिप्ट:

class CreateMyLogsTable extends Migration { 

    public function up() 
    { 
     Schema::create('my_logs', function(Blueprint $table) { 
      $table->increments('id'); 
     }); 

     DB::statement('ALTER TABLE `my_logs` ADD `ip_address` VARBINARY(16)'); 
    } 

    public function down() 
    { 
     DB::statement('ALTER TABLE `my_logs` DROP COLUMN `ip_address`'); 

     Schema::drop('my_logs'); 
    } 
} 

जाहिर है इसके बाद के संस्करण केवल महत्वपूर्ण हिस्सा डीबी :: बयान (...) है। हमें कच्चे प्रश्नों का उपयोग Taylor Otwell suggested के रूप में करने की आवश्यकता है। अपनी मेज को बाकी तरीके से बनाने के लिए स्वतंत्र महसूस करें।

यहां से आप PHP के inet_pton() और inet_ntop() का उपयोग आईपी एड्रेस स्ट्रिंग को बाइनरी में बदलने के लिए और इसके विपरीत कर सकते हैं।

सकारात्मक:

  1. विकल्प 1
  2. की तुलना में अंतरिक्ष बचाता विकल्प 2
की तुलना में
  • बेहतर डीबी प्रदर्शन

    विपक्ष:

    1. जैसा विकल्प 2, आपको या तो मैनुअल करना होगा y बाइनरी और मानव-पठनीय स्ट्रिंग के बीच आगे और पीछे परिवर्तित करें, या एक जोड़ी कस्टम एक्सेसर/म्यूटेटर के साथ इलोक्वेंट मॉडल का उपयोग करें जो मैं नीचे दिखाऊंगा।

    अतिरिक्त क्रेडिट: कस्टम सुवक्ता एक्सेसर/mutator जोड़ें (वैकल्पिक):

    यहाँ जहां मैं बोलने में निपुण वास्तव में उपयोगी पाते है। आप अपने स्वयं के एक्सेसर/म्यूटेटर को अपने इलोकेंट मॉडल पर सेट कर सकते हैं और आप सामान्य रूप से अपने मॉडल के इंस्टेंस वैरिएबल के माध्यम से/सेट कर सकते हैं।

    class MyLog extends Eloquent { 
    
        public $timestamps = false; 
    
        public function getIpAddressAttribute($value) 
        { 
         return inet_ntop($value); 
        } 
    
        public function setIpAddressAttribute($value) 
        { 
         $this->attributes['ip_address'] = inet_pton($value); 
        } 
    } 
    

    अब अगर आप कार्य करें:

    $log = new MyLog; 
    $log->ip_address = '192.168.0.1'; 
    $log->save(); 
    

    आईपी पते सही ढंग से बाइनरी के रूप में सहेज लिया जाएगा। और आप कर सकते हैं:

    $log = MyLog::find(1); 
    echo $log->ip_address; 
    

    और यह 1 9 2.168.0.1 को प्रतिबिंबित करेगा। बहुत उपयोगी!

  • +0

    प्रदान किए गए चरणों का उपयोग करके, आईपी एड्रेस को एक लंबी बाइनरी के रूप में डाला गया और डेटाबेस से इसे लाने पर यह '7f00: 1 ::' लौटा। डेटाबेस में भेजा गया आईपी '127.0.0.1' था। '1 9 2.168.0.1' के आपके उदाहरण का उपयोग करके 'c0a8: 1 ::' यह विकल्प 3 का उपयोग कर रहा है। – davidxd33

    +0

    @ davidxd333 धन्यवाद इसे हाइलाइट करने के लिए धन्यवाद। यह भंडारण के दौरान आईपीवी 4 पते पर पैन शून्य के लिए पैन शून्य की वजह से है। जैसा कि कानिन पेनवीरियाकुलकिट ने नीचे एक और जवाब में उल्लेख किया है, हमें वास्तव में बिनरी के बजाय वर्बिनरी का उपयोग करने की आवश्यकता है। मैंने शब्दावली के लिए अपना जवाब संशोधित किया है। – Unnawut

    +0

    'डाउन' विधि में 'डीबी :: कथन (...)' आवश्यक है? – Matthew

    0

    @Unnawut से।

    यदि आप उसी क्षेत्र में ipv4 और ipv6 दोनों से निपटना चाहते हैं तो आपको binary(16) से varbinary(16) में बदलने की आवश्यकता है।

    लेकिन आप केवल आईपी v4 निपटने के लिए की जरूरत है सिर्फ INT UNSIGNED

    आप केवल आईपी v6 निपटने के लिए चाहते हैं BINARY(16)

    रेफरी: MYSQL - SELECT IP v4/v6, inet_pton & bin2hex

    ref2: https://stackoverflow.com/a/5133610/2126472

    +0

    के बाद पूरी तालिका लाइन को छोड़ रहे हैं! यह बात बताने के लिए धन्यवाद। एसओ पर भी परिचित नाम देखने के लिए खुशी हुई! : डी – Unnawut

    +0

    आह! आपको भी देखकर खुशी हुई। –

    संबंधित मुद्दे