# الترميز في ( Mysql )  (موضوع مهم جدا )



## Yes_Or_No (4 يونيو 2006)

*الترميز في ( Mysql )  (موضوع مهم جدا )*

*الترميز بإختصار هو عباره عن إعطاء رمز لحرف من الحروف أو علامه من العلامات أو رقم من الأرقام.
على سبيل المثال:
لو كان لدينا الجمله التاليه:
aBaD$1
فنقول مثلاً 
حرف a نرمز له بالرقم 1
والحرف B نرمز له بالرقم 2
والحرف D نرمز له بالرقم 3
والعلامه $ نرمز له بالرقم 4
والرقم 1 نرمز له بالرقم 5
فيصبح ترميز الجمله السابقه
121345

أكيد سيسأل السائل ويقول: ما الفائده من هذا الترميز للحروف وللأرقام؟
الجواب بسيط وهو لأن الكمبيوترات لا تعرف إلا الصفر والواحد ( النظام الثنائي ) لذلك نرمز لهذه الحروف بسلسله من الأرقام الثنائيه الصفر والواحد فقط حتى يفهم الكمبيوتر طلبنا بعد ذلك.

أيضاً سيسأل السائل ويقول: ولكن في مثالنا السابق رمزنا للحروف بأرقام 121345 وأنت ذكرت بأن الكمبيوتر لا يفهم إلا الصفر والواحد؟
الجواب بسيط وهو أن لكل سلسله ثنائيه من الصفر والواحد(binary) لها مايقابلها بالسلسله العشريه [0-9](decimal) وكذلك السلسله العشريه لها مايقابلها بالسلسله السدس عشريه[0-9][a-f]ـ(hexdeciaml) لذلك إختصاراً لطول الرقم الذي سيكتب بالسلسله الثنائيه كتبناه بالنظام العشري في المثال السابق لكي تسهل علينا قراءة الرمز.

الان بعد أن عرفنا الغايه التي وضع الترميز لأجلها دعونا نعرف ماهي الحروف التي سنرمز لها وماهي الأشكال والأرقام ..... الخ
في بداية ظهور الترميز تم عمل جدول يسمى جدول ASCII وهي إختصار لـ (American Standard Code for Information Interchange ) طبعا من الإسم واضح إنه أمريكي 
	

	
	
		
		

		
			





 وهذا الجدول يشمل لكل مايراد ترميزه في الحاسب في تلك الفتره لذلك لم يكن الإهتمام بكل الحروف ولكن كان الاهتمام بالحروف الانجليزيه فقط وبعض الإشارات المعروفه في ذلك الوقت بحكم إنهم أمريكان طبعاً 
	

	
	
		
		

		
		
	


	



لذلك تم عمل جدول الـ ascii من 128 خانه وكان طول الحرف في هذا الجدول 7 بت لذلك كان عيبه بأنه ليس ملائم لطول البايت الذي يعادل 8 بت وفي نفس الوقت كانت تنقصه بعض رموز النظام وعلامات أخرى لذلك تمت توسعته الى 256 خانه والصوره التاليه تبين جدول الـ ASCII وتشاهدوا فيها كل حرف والرمز الذي أعطي له بالنظام العشري deciaml 





ملاحظات:
1-البايت الواحد يساوي 8 بت وبمعادله بسيطه نعرف عدد الخانات في البايت وهي : 2^8 = 256 خانه.
2- الجدول السابق في الصوره تم ترميز الحروف فيه بالنظام العشري لذلك لو تم تحويل كل رقم من هذه الأرقام الى النظام الثنائي ستظهر معك سلسله طويله من أرقام النظام الثنائي.


بعد تقدم عصر الكمبيوتر أصبح المطورون في شتى أنحاء العالم ينظرون الى تطوير الجدول السابق بنظام يشمل حروف اللغات الأخرى، فتوصلوا لفكرة أن يكون لكل لغه مجموعة ترميز ( مجموعة محارف ) خاصه بها، تتكون هذه المجموعه من جدول سعته 256 خانه ( بايت ) وفي نفس الوقت جدول لقانون لهذه اللغه.
جدول القانون هو عباره عن قواعد رياضيه توضّح فيها العلاقه بين الحروف والعلامات.
على سبيل المثال في اللغه الإنجليزيه حرف a الاسمول يساوي حرف A الكابتل وفي اللغه العربيه حرف ( ل المنفصل ) يساوي حرف ( لـ المتصل ) .... الخ من القوانين المتبعه في كل لغه.

أمثله على أسماء مجموعات ترميز :
windows-1252 وهو خاص باللغات اللاتينيه ( الانجليزيه + الألمانيه + الأسبانيه + الدنماركيه + النرويجيه + السويديه ).
windows-1256 وهو خاص باللغة العربيه .
windows-1255 وهو خاصه باللغه العبرية .

كل مجموعات الترميز السابقه طول الحرف فيها 8 بت وحيث أن لكل لغه جدول خاص بها فقد كان متعباً للمطورين بالبحث عن إسم الترميز للغه المطلوبه لذلك تم تطوير هذا النظام مره أخرى أيضاً بحيث تكون كل حروف لغات العالم مكتوبه بجدول واحد فقط وهو النظام العالمي المشهور بالـ UNICODE حيث يكون طول الحرف فيه 16 بت يعني لو طبقنا المعادله السابقه وقلنا : 2^16=65536 خانه !! ( وش يعبيها؟!؟ ).
لذلك أي حرف مكتوب بترميز اليونيكود يساوي حرفين في أي ترميز اخر وهذا هو السبب الرئيسي الذي يزيد من حجم أي صفحه مخزنه بنظام ترميز اليونيكود.

لن أخوض في التفاصيل التاريخيه أكثر من ذلك ولكن كانت هذه نبذه توضيحيه حتى أستطيع أن أبدأ هذا الموضوع بوضوح.

لمزيد من التفاصيل التاريخيه أدخل على الروابط التاليه:
**http://tronweb.super-nova.co.jp/characcodehist.html*
*http://www.wps.com/projects/codes/*
*http://www.terena.nl/library/multil...roml/mlcs5.html*

*ندخل بموضوعنا الان

تم دعم الترميز (مجموعات المحارف) في الإصدارات 4.1 ومافوق من نظام قواعد البيانات المجاني MySQL لذلك القاريء لهذا الموضوع والذي يستخدم إصدارات أقدم من إصدار 4.1 مثل إصدار 4.0 أو إصدار 3.8 فلن يستفيد من هذا الموضوع وعليه الإنصراف فوراً 
	

	
	
		
		

		
		
	


	




 أو البقاء لمعرفة هذه الميزه الجباره في إصدارات 4.1 ومافوق 
	

	
	
		
		

		
		
	


	




ساستخدم مصطلحين في حديثي:
الأول charset ويقصد به الترميز المستخدم.
الثاني collation ويقصد به القانون المستخدم للترميز كما أشرنا لذلك سابقاً.

لإظهار مجموعات الترميز المستخدمه في إصدار الـ mysql الخاص بك قم بتنفيذ الأمر التالي في الـ phpMyAdmin أو أي سكربت اتصال بالـ mysql:
*
*كود HTML:*
*show character set;*​

*سيظهر لك جدول يوضح إسم كل مجموعة ترميز مع الوصف والقانون الإفتراضي المستخدم لهذا الترميز وطول الحرف الواحد.
*
*كود HTML:*
*+----------+-----------------------------+---------------------+--------+| Charset  | Description                 | Default collation   | Maxlen |+----------+-----------------------------+---------------------+--------+| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |      2 || dec8     | DEC West European           | dec8_swedish_ci     |      1 || cp850    | DOS West European           | cp850_general_ci    |      1 || hp8      | HP West European            | hp8_english_ci      |      1 || koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |      1 || latin1   | cp1252 West European        | latin1_swedish_ci   |      1 || latin2   | ISO 8859-2 Central European | latin2_general_ci   |      1 || swe7     | 7bit Swedish                | swe7_swedish_ci     |      1 || ascii    | US ASCII                    | ascii_general_ci    |      1 || ujis     | EUC-JP Japanese             | ujis_japanese_ci    |      3 || sjis     | Shift-JIS Japanese          | sjis_japanese_ci    |      2 || hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |      1 || tis620   | TIS620 Thai                 | tis620_thai_ci      |      1 || euckr    | EUC-KR Korean               | euckr_korean_ci     |      2 || koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |      1 || gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   |      2 || greek    | ISO 8859-7 Greek            | greek_general_ci    |      1 || cp1250   | Windows Central European    | cp1250_general_ci   |      1 || gbk      | GBK Simplified Chinese      | gbk_chinese_ci      |      2 || latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |      1 || armscii8 | ARMSCII-8 Armenian          | armscii8_general_ci |      1 || utf8     | UTF-8 Unicode               | utf8_general_ci     |      3 || ucs2     | UCS-2 Unicode               | ucs2_general_ci     |      2 || cp866    | DOS Russian                 | cp866_general_ci    |      1 || keybcs2  | DOS Kamenicky Czech-Slovak  | keybcs2_general_ci  |      1 || macce    | Mac Central European        | macce_general_ci    |      1 || macroman | Mac West European           | macroman_general_ci |      1 || cp852    | DOS Central European        | cp852_general_ci    |      1 || latin7   | ISO 8859-13 Baltic          | latin7_general_ci   |      1 || cp1251   | Windows Cyrillic            | cp1251_general_ci   |      1 || cp1256   | Windows Arabic              | cp1256_general_ci   |      1 || cp1257   | Windows Baltic              | cp1257_general_ci   |      1 || binary   | Binary pseudo charset       | binary              |      1 || geostd8  | GEOSTD8 Georgian            | geostd8_general_ci  |      1 || cp932    | SJIS for Windows Japanese   | cp932_japanese_ci   |      2 |+----------+-----------------------------+---------------------+--------+*​

*تم وضع شروط أساسيه لهذه المجموعات:
1- لا يمكن لمجموعتي ترميز مختلفه إستخدام قانون واحد.
2- لكل مجموعة ترميز قانون إفتراضي يتم إختياره في حالة لم يحدد هذا القانون.
3- تم عمل تقليد لأسماء القوانين بحيث يبدأ الإسم بإسم مجموعة الترميز متبوعاً بإسم اللغه المربوطه بهذه المجموعه وينتهي بهذا الإسم بمايلي:
_ci وتعني (case insensitive) أي بمعنى تجاهل تحسس حالة الأحرف بحيث يكون حرف a الأسمول يساوي حرف الـ A الكابتل.
_cs وتعني (case sensitive) أي بمعنى تطبيق تحسس حالة الأحرف وهي عكس السابقه ci .
_bin وتعني (binary) وتعني أخذ الرمز بدلاً من الحرف وهذا القانون يفيد في حالة التحويل وسنتطرق لإستخدامه فيما بعد.

السؤال المهم هنا:
هل يوجد لكل مجموعة ترميز، أكثر من قانون ؟
الجواب نعم.

نفذ الأمر التالي:
*
*كود HTML:*
*SHOW COLLATION LIKE 'latin1%';*​

*سيظهر لك الجدول التالي:
*
*كود HTML:*
*+---------------------+---------+----+---------+----------+---------+| Collation           | Charset | Id | Default | Compiled | Sortlen |+---------------------+---------+----+---------+----------+---------+| latin1_german1_ci   | latin1  |  5 |         |          |       0 || latin1_swedish_ci   | latin1  |  8 | Yes     | Yes      |       1 || latin1_danish_ci    | latin1  | 15 |         |          |       0 || latin1_german2_ci   | latin1  | 31 |         | Yes      |       2 || latin1_bin          | latin1  | 47 |         | Yes      |       1 || latin1_general_ci   | latin1  | 48 |         |          |       0 || latin1_general_cs   | latin1  | 49 |         |          |       0 || latin1_spanish_ci   | latin1  | 94 |         |          |       0 |+---------------------+---------+----+---------+----------+---------+*​

*ستلاحظ أنه عند إختيارك لترميز latin1 في قاعدة بياناتك يجب أن تحدد القانون المستخدم فيها، لأن هناك أكثر من لغه لاتينيه في هذا الترميز لها قانون فإذا لم تحدد القانون فيها فسوف يتم إختيار القانون الإفتراضي لهذا الترميز وهو latin1_swedish_ci .
ترميز الـ latin1 في الـ mysql هو نفسه ترميز windows-1252 الذي ذكرناه سابقاً.
*

*+++++++++++*

*الترميز الذي يهمنا في الموضوع هو ترميز اللغه العربيه cp1256 وهو نفسه ترميز windows-1256 الذي ذكرناه سابقاً وبه قانونين يمكن تطبيقها وهي:
1- القانون الإفتراضي cp1256_general_ci .
2- القانون الثنائي cp1256_bin .

لذلك حتى نفهم كيف نطبق هذا الترميز مع قانونه الإفتراضي على قواعد البيانات الخاصه بنا يجب معرفة الطبقات الترميزيه في الـ mysql 

1- الطبقات الداخليه ( داخل الخادم ) :
الطبقه الأولى : ترميز وقانون الخادم( server charset and collation )
الطبقه الثانيه : ترميز وقانون قاعدة البيانات ( database charset and collation )
الطبقه الثالثه : ترميز وقانون الجدول ( table character set and collation )
الطبقه الرابعه : ترميز وقانون الحقل ( column character set and collation )

2- الطبقات الخارجيه ( اتصال العميل بالخادم ) :
الطبقه الأولى: ترميز وقانون الإتصال ( connection character set and collation).
الطبقه الثانيه: ترميز وقانون العميل ( client character set and collation ).
الطبقه الثالثه: ترميز وقانون النتائج ( result character set and collation)

كل هذه الطبقات يتم تطبيقها من الطبقه العليا الى الطبقه السفلى.

على سبيل المثال:
إذا لم تحدد ترميز وقانون طبقة النتائج فسوف يتم إستخدام ترميز وقانون طبقة العميل لهذه الطبقه وإذا لم تحدد ترميز وقانون طبقة العميل أيضاً فسوف يستخدم ترميز وقانون طبقة الإتصال لهذه الطبقتين وإذا لم تحدد لهذه الطبقات كلها أي ترميز فسوف يستخدم الترميز الإفتراضي وهو latin1 مع قانون latin1_swedish_ci.
ونفس الكلام ينطبق على الطبقات الداخليه من الطبقه العليا الى الطبقه السفلى.

لنبدأ بإنشاء قاعدة بيانات ذات ترميز اللغه العربيه cp1256
نفذ الأمر التالي في الـ phpMyAdmin أو أي سكربت اتصال بالـ mysql :
*
*كود HTML:*
*CREATE DATABASE arabic_db CHARACTER SET cp1256;*​

*سوف يقوم الخادم بإنشاء قاعدة بيانات إسمها arabic_db بترميز cp1256 ولأننا لم نحدد القانون المستخدم فسوف يستخدم القانون الإفتراضي لترميز اللغه العربيه وهو cp1256_general_ci .

نقوم بإنشاء جدول بترميز اللغه العربيه cp1256 
نفذ الأمر التالي:
*
*كود HTML:*
*CREATE TABLE al3ndaleeb(    f1 CHAR(10) ) DEFAULT CHARACTER SET cp1256;*​

*قمنا بإنشاء جدول بترميز cp1256 ووضعنا فيه حقل إسمه f1 ولأننا لم نحدد ترميز لغة الحقل فسوف يستخدم ترميز الجدول كما أشرنا لهذا في الطبقات وأيضاً لأننا لم نحدد القانون في الجمله فسوف يستخدم القانون الإفتراضي لترميز اللغه العربيه وهو cp1256_general_ci .

السؤال المهم هنا:
هل نستطيع أن نقوم بإنشاء جدول ذو حقول ذات تراميز مختلفه ؟
الجواب نعم 
	

	
	
		
		

		
		
	


	



وهذه ميزه جباره في طريقة تخزين البيانات داخل الجداول .

الان أصبحت طبقات الترميز الداخليه في مثالنا كالتالي:
1- ترميز الخادم ( الترميز الإفتراضي latin1 )
2- ترميز القاعده ( الترميز العربي cp1256 )
3- ترميز الجدول ( الترميز العربي cp1256 )
4- ترميز الحقل ( لم يحدد )

لماذا ظهر ترميز latin1 في الخادم؟
الجواب: لأن الخادم إفتراضياً يستخدم هذا الترميز إلا إذا قام المدير العام للخادم ( المستضيف ) بوضع الترميز العربي إفتراضياً للخادم وهذا هو المفروض الذي يقوم به أي مستضيف خدمه ( حسره على المستضيفين العرب تاركين كل شي على الوضع الإفتراضي ) .
ماذا يعني ؟ هل ستصبح نتائجنا كلها بالـ latin1 ؟؟
الجواب : بالطبع لا فسوف نستطيع تغيير قيمة ترميز الخادم عند الإتصال!!! 
	

	
	
		
		

		
		
	


	



كيف ؟
الطريقه سهله وهو في كل إتصال نرسل الأمر التالي للخادم:
*
*كود HTML:*
*set character_set_server='cp1256';*​


*سؤال مهم:
كيف نعدل ترميز الطبقات الخارجيه ؟
عن طريق الأمر التالي:
*
*كود HTML:*
*set names cp1256;*​

*وسوف يقوم الأمر بوضع الترميز العربي لكل الطبقات الخارجيه لذلك عند الإتصال بالقاعده من أي سكربت يجب إرسال الأمرين السابقه مع بعض.
*
*كود HTML:*
*set character_set_server='cp1256';set names cp1256;*​ 

*منقووووووووووووووووووووووووول للفائده لاصحاب المنتديات  
​*


----------



## ThE GrEaT OnE (8 سبتمبر 2006)

الموضوع ده مهم جدا بنصح الكل يقرووه

وحصلتلي بسببه مشاكل كتير وانا بنقل الداتا بيز بتاعت منتدايا  لسيرفر جديد

وشكرا


----------



## My Rock (8 سبتمبر 2006)

*موضوع مفيد يا يس اور نو*

*مشكور عليه*


----------

